package com.sun.solarisinstall.panels;

import java.io.*;
import java.util.*;
import com.sun.wizards.core.*;
import com.sun.install.products.*;
import com.sun.solarisinstall.tasks.*;

public class ProfileServerObject implements ServerObject, Serializable
{
  private transient WizardState wizardState = null;
  private transient Profile profile = null;

  public ProfileServerObject()
  {

  }

  public void setWizardState(WizardState wizardState)
  {
    this.wizardState = wizardState;
  }

  /**
   * Get the runtime classes required by this ServerObject.
   */
  public void addRuntimeResources(Vector resourceVector)
  {
    resourceVector.addElement(new String[] {null, 
			 "com.sun.solarisinstall.panels.ProfileServerObject"});
  }

  public void initProfile()
  {
    setPlatform();
    String name = wizardState.getPurpose() + " " + wizardState.getName();
    //String prodName=(String)wizardState.getData(InstallConstants.productName);
    String prodName = (String)wizardState.getData(ProfileConstants.mediaName);
    String osName = (String)wizardState.getData(ProfileConstants.osName);
    if (Def.DEBUG) System.out.println("PSO initProfile prodname="+prodName);
    if (Def.DEBUG) System.out.println("PSO initProfile osName="+osName);
    ProfileUtil.reloadInfo(prodName,osName);
    Vector localeIDList = ProfileUtil.getLocaleIDList();
    Vector localeList = ProfileUtil.getLocaleList();
    wizardState.setData(ProfileConstants.OSlocaleIDs, localeIDList);
    wizardState.setData(ProfileConstants.OSlocales, localeList);
    Profile profile = ProfileUtil.getProfile();
    wizardState.setData("SolarisInstallProfile", profile);
    wizardState.setData("DefaultCluster", profile.getCluster());
    wizardState.setData(ProfileConstants.CD0SwapSlice, 
			PartitionInfo.getDefaultSwapSlice());
    setUpgradeable();
    set64Bit(profile);
  }

  /*
   * Read one line from a file
   */

  public String readFileLine(String filePath) {

    String line=null; 
    FileInputStream stream=null;
    File file = new File(filePath);

    try {
       stream = new FileInputStream(file);
       BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
       line = reader.readLine();
       if (line != null) line = line.trim();
       if (Def.DEBUG) System.out.println("readFileLine: [" + line + "] from " + filePath);
    } catch(IOException e) {
      System.err.println("readFileLine: Could not read " + filePath);
      e.printStackTrace();
    }
    if (stream != null) try {
	stream.close();
    } catch(IOException e) {
      e.printStackTrace();
    }

    return(line);
  }

  /*
   * read the platform we are running on from the unamePlatformBase file
   */
  public void setPlatform()
  {
    ProfileConstants.platform = readFileLine(ProfileConstants.unamePlatformBase);

    if (ProfileConstants.platform == null) {
      System.err.println ("Couldn't read platform -- using sparc.");
      ProfileConstants.platform = "sparc";
      return;
    }

    ProfileConstants.platformBase = "/" + ProfileConstants.platform;
  }


  /*
   *  see if the system is upgradeable
   */
  public void setUpgradeable()
  {
    File upgradeFile = new File(ProfileConstants.installUpgradeInfo);

    BufferedReader upgradeRdr;
    FileInputStream upgradeStream;
    try {
       upgradeStream = new FileInputStream(upgradeFile);
       upgradeRdr = new BufferedReader(new InputStreamReader(upgradeStream));
       String tmp;
       int i = 0;
       Vector rootDevice = new Vector();
       Hashtable ht = new Hashtable();
       while ((tmp = upgradeRdr.readLine()) != null)
	 {
	   String disk;
	   String os;
	   String release;
	   StringTokenizer st = new StringTokenizer(tmp);
	   boolean first = true;
	   int numTok = st.countTokens();
	   if ( numTok == 3 ) {
	     disk = st.nextToken();
	     os = st.nextToken();
	     release = st.nextToken();
	     Vector osVector= new Vector();
	     osVector.addElement(os);
	     osVector.addElement(release);
	     ht.put(disk, osVector);
	     rootDevice.addElement(disk);
	   } else {
	     System.err.println("Line " + tmp + " in " + ProfileConstants.installUpgradeInfo + " is missing some elements, skipping");
	   }
	   i++;
	 }
       if ( rootDevice.size() > 0 ) {
	 //System is upgradeable
	 wizardState.setData("SolarisInstallNotUpgradeable", new Boolean(false));
	 Profile profile = ProfileUtil.getProfile();
	 // initialize rootdevice to first item for a start.
	 profile.setRootDevice((String) rootDevice.firstElement());
	 wizardState.setData("rootDevice", rootDevice);
	 wizardState.setData("rootHT", ht);
       
	 if ( rootDevice.size() > 1 ) {
	   // System has more than one upgradeable root partition
	   if (Def.DEBUG) System.out.println("more than one root filesystem");
	   wizardState.setData("oneroot", new Boolean(false));
	 }
       }
    } catch(IOException e) {
      wizardState.setData("SolarisInstallNotUpgradeable", new Boolean(true));
      return;
    }
    try {
      upgradeStream.close();
    } catch(IOException e) {
    }
    return;
  }

  public void setRootDevice() {
    String rootDevice = (String)wizardState.getData("rootDevice");
    if (Def.DEBUG) System.out.println("Setting root device to " + rootDevice);
    Profile profile = ProfileUtil.getProfile();
    profile.setRootDevice(rootDevice);
  }

  public Boolean checkSolImage()
  {
    /*
     * If changes made to logic, check getInstallLangs to
     * see if similar changes necessary
     */
    File osFile251 = new File("/cdrom/Solaris_2.5.1");
    if (osFile251.exists()) {
      if (Def.DEBUG) System.out.println("\nHave image for Solaris 2.5.1");
      return(new Boolean(true));
    }

    Vector OSes = new Vector();
    OSes.addElement("Solaris_2.6");
    OSes.addElement("Solaris_2.7");
    OSes.addElement("Solaris_8");
    for (int i=0; i < OSes.size(); i++) {
      File osFile = new File("/cdrom/" + OSes.elementAt(i) + "/Product");
      if (osFile.exists()) {
        if (Def.DEBUG)System.out.println("\nHave image for "+OSes.elementAt(i));
        return(new Boolean(true));
      }
    }
    return(new Boolean(false));
  }


  public void addCDProducts(String productTocPath, Boolean defaultCDinstall)
  {
    ProfileUtil.addNewProducts(productTocPath, defaultCDinstall);
  }

  public Vector getCDList()
  {
    /*
     * Reads from media_kit.toc and returns vector containing
     * CD Name for each CD.
     */
    Vector cdList = new Vector();
    String mktoc = ProfileUtil.getMediaKitDir() + ProfileConstants.mediaKitToc;
    File mktocFile = new File(mktoc);
    if (!mktocFile.exists()) return(cdList);

    BufferedReader mktocRdr;
    FileInputStream mktocStream;

    try {
       mktocStream = new FileInputStream(mktocFile);
       mktocRdr = new BufferedReader(new InputStreamReader(mktocStream));
    } catch(IOException e) {
        System.out.println("Error opening file " + mktoc + ".");
        return (cdList);
    }

    try {
      String line;
      while ((line = mktocRdr.readLine()) != null) {
        line = line.substring(line.indexOf(' ')).trim();
        cdList.addElement(line);
      }
    } catch (IOException ex) {
        System.err.println("Error reading file " + mktoc + ".");
    }

    try {
      mktocStream.close();
    } catch(IOException e) {
    }

    return (cdList);
  }


  /*
   * Returns vector containing SolarisProducts for given cd.
   * SolarisProducts must already exist in the ProfileUtil productlist.
   *
   * NOTE: Products returned have defaultInstall reset to
   *       value from product.toc only. Previous defaultInstall 
   *       took CD default into account (see createProducts).
   */
  public Vector getCDProductList(String CDName)
  {
    Vector prodList = new Vector();
    Vector realProdListCopy = ProfileUtil.getProductList();
    Vector realProdList = (Vector)realProdListCopy.clone();
    Vector prodNames = new Vector();

    /*
     * get the product.toc path from the cdname
     */
    String productToc = getProductTocFromCDName(CDName);
    File prodTocFile = new File(productToc);
    if (!prodTocFile.exists()) return(prodList);

    BufferedReader prodTocRdr;
    FileInputStream prodTocStream;

    try {
       prodTocStream = new FileInputStream(prodTocFile);
       prodTocRdr = new BufferedReader(new InputStreamReader(prodTocStream));
    } catch(IOException e) {
        System.out.println("Error opening file " + productToc + ".");
        return (prodList);
    }

    Vector prodVec = new Vector();
    try {
      String line;
      while ((line = prodTocRdr.readLine()) != null) {
        prodVec.addElement(line);
      }
    } catch (IOException ex) {
        System.err.println("Error reading file " + productToc + ".");
    }

    try {
      prodTocStream.close();
    } catch(IOException e) {
    }

    /*
     * See if SolarisProduct exists for each prod in product.toc
     * Skip duplicate entries.
     */
    for (int i=0; i < prodVec.size(); i++) {
      String line = (String)prodVec.elementAt(i);
      String pdProdName;
      boolean install = false;
      if (line.indexOf(" ") >= 0) {
        pdProdName = line.substring(0,line.indexOf(" ")).trim();

        if (prodNames.contains(pdProdName)) continue;
        String installParams = line.substring(line.indexOf(" ")).trim();
        if (installParams.indexOf(" ") >= 0) {
          install = (installParams.substring(0,installParams.indexOf(" ")).trim()).equalsIgnoreCase("YES");
        } else {
          install = installParams.equalsIgnoreCase("YES");
        }

        for (int k=0; k < realProdList.size(); k++) {
          SolarisProduct prod = (SolarisProduct)realProdList.elementAt(k);
          String file = prod.getFilename().trim();
          if (file.startsWith(ProfileConstants.osFilePrefix)) continue;
          if (file.startsWith(ProfileConstants.pdFilePrefix)) {
              file = file.substring(ProfileConstants.pdFilePrefix.length());
          }
          if (pdProdName.equals(file) && CDName.equals(prod.getCDname())) {
            if (Def.DEBUG) System.out.println("getCDProductList adding " 
                   + pdProdName + " on " + CDName + " to list, panel default="
                   + install);
            prod.setInstalledByDefault(install);
            prodList.addElement(prod);
            prodNames.addElement(pdProdName);
          }
        } 
      }
    }
    return (prodList);
  }



  private static String getProductTocFromCDName(String cdName) 
  {
    /*
     *  Returns path to individual product.toc file
     */
    String prodDir = null;
    String mkToc = ProfileUtil.getMediaKitDir() + ProfileConstants.mediaKitToc;
    File mkTocFile = new File(mkToc);
    if (!mkTocFile.exists()) return(prodDir);

    BufferedReader mkTocRdr;
    FileInputStream mkTocStream;

    try {
       mkTocStream = new FileInputStream(mkTocFile);
       mkTocRdr = new BufferedReader(new InputStreamReader(mkTocStream));
    } catch(IOException e) {
        System.out.println("Error opening file " + mkToc + ".");
        return (prodDir);
    }

    try {
      String line;
      String newline;
      while ((line = mkTocRdr.readLine()) != null) {
        if (line.substring(line.indexOf(" ")).trim().equals(cdName)) {
          prodDir =
            ProfileConstants.CDsBaseDir + "/" +
              line.substring(0,line.indexOf(" ")).trim() +
                ProfileConstants.productToc;
          break;
        }
      }
    } catch (IOException ex) {
        System.err.println("Error reading file " + mkToc + ".");
    }

    return prodDir;
  }


  /*
   *  Returns Hashtable containing cd.info file attributes
   */
  public static Hashtable getCDinfo(String cdInfoPath) 
  {
    boolean done = false;
    BufferedReader cdInfo;
    FileInputStream cdInfoStream;
    Hashtable cdhash = new Hashtable();

    if (cdInfoPath == null) {
      if (Def.DEBUG) System.out.println("getCDinfo: null cdInfoPath");
      return(cdhash);
    }

    File cdInfoFile = new File(cdInfoPath);
    try {
        cdInfoStream = new FileInputStream(cdInfoFile);
        cdInfo = new BufferedReader(new InputStreamReader(cdInfoStream));
    } catch(IOException e) {
        System.out.println("Error opening file " +
                           cdInfoFile.getPath() +
                           ".");
        return(cdhash);
    }
    while (!done) {
      try {
        String line = cdInfo.readLine();
        if (line==null)
          done = true;
        else {
          int equalsPosition = line.indexOf('=');
          if (equalsPosition > 0) {
            String attribute = line.substring(0, equalsPosition);
            String value = line.substring(equalsPosition+1);

        //System.out.println("cdinfo: attribute="+attribute+" value="+value);

            cdhash.put(attribute, value);

          }
        }
      } catch (IOException ex) {
        done = true;
        System.err.println("Error reading file " +
                           cdInfoFile.getPath() + ".");
      }
    }
    try {
        cdInfoStream.close();
    } catch(IOException e) {
    }
    return cdhash;
  }


  public static String getCDMouseText(String cdname) 
  {
     String help_path = null;
     String fullPath = null;
     String helpText = null;

    /*
     *  Returns path to individual cd.info file
     */
    String cdinfoPath = getCDinfoFromCDName(cdname);
    if (cdinfoPath == null) return("");
    /*
     * Truncate off the /cd.info
     */
    int cdinfoIndex = cdinfoPath.indexOf(ProfileConstants.cdInfo);
    String path = cdinfoPath.substring(0,cdinfoIndex);
   
    /*
     * Now get the cd directory name
     */
    int slashIndex = path.lastIndexOf(File.separator);
    String dirname = path.substring(slashIndex+1);

    String locid = getMiniRootLocale();

    String leadingPath = ProfileConstants.CDsBaseDir +ProfileConstants.helpBase;

    helpText = getMouseText(leadingPath, dirname);

    return(helpText);

  }

  public static String getProdMouseText(String pdName) 
  {
     String help_path = null;
     String fullPath = null;
     String helpText = null;

    String locid = getMiniRootLocale();

    String leadingPath = ProfileConstants.mousehelpDir;
    helpText = getMouseText(leadingPath, pdName);

    return(helpText);

  }


  public static String getMouseText(String leadingPath, String filename) 
  {
     String help_path = null;
     String fullPath = null;
     String helpText = null;

    String locid = getMiniRootLocale();

    if (locid != null) {
      help_path = locid.concat(File.separator + filename);
      fullPath = leadingPath + File.separator + help_path;
      File fullPathFile = new File(fullPath);
      if (! fullPathFile.exists()) {
        if (locid.length() > 1) {
          locid = locid.substring(0,2);
        }
        help_path = locid.concat(File.separator + filename);
        fullPath = leadingPath + File.separator + help_path;
        fullPathFile = new File(fullPath);
        if (! fullPathFile.exists())  {
           help_path = "C" + File.separator + filename;
        }
      }
    } else {
      help_path = "C" + File.separator + filename;   
    }

    fullPath = leadingPath + File.separator + help_path;
    File fullPathFile = new File(fullPath);
    if (! fullPathFile.exists()) {
      return("");
    } else {
      helpText = readInText(fullPath);
    }

    return(helpText);

  }


  public static String getCDinfoFromCDName(String cdName) {
    /*
     *  Returns path to individual cd.info file
     */
    String cdInfo = null;
    boolean done = false;
    BufferedReader mediaKitToc;
    FileInputStream mKitStream;

    String mediaKitDir = ProfileUtil.getMediaKitDir();
    String mediaKitTocPath = mediaKitDir + ProfileConstants.mediaKitToc;

    File mKitFile = new File(mediaKitTocPath);
    try {
        mKitStream = new FileInputStream(mKitFile);
        mediaKitToc = new BufferedReader(new InputStreamReader(mKitStream));
    } catch(IOException e) {
        System.out.println("Error opening file " +
                           mKitFile.getPath() +
                           ".");
        return("Error");
    }
    while (!done) {
      try {
        String line = mediaKitToc.readLine();
        if (line==null)
          done = true;
        else {
          if (line.substring(line.indexOf(" ")).trim().equals(cdName)) {
            cdInfo = ProfileConstants.CDsBaseDir + "/" +
                        line.substring(0,line.indexOf(" ")).trim() +
                        ProfileConstants.cdInfo;
            break;
          }
        }
      } catch (IOException ex) {
        done = true;
        System.err.println("Error reading file " +
                           mKitFile.getPath() + ".");
      }
    }
    try {
        mKitStream.close();
    } catch(IOException e) {
    }
    return cdInfo;
  }


  /*
   * get list of media kits on cd0 cd
   */
  public Vector getMediaKitList()
  {
    String mkitsToc = ProfileConstants.mediaKitsToc;
    Vector mkList = new Vector();
    File mediaKitsToc = new File(mkitsToc);
    if (! mediaKitsToc.exists()) return(mkList);

    boolean done = false;
    BufferedReader mediaKit;
    FileInputStream mediaKitStream;

    try {
        mediaKitStream = new FileInputStream(mediaKitsToc);
        mediaKit = new BufferedReader(new InputStreamReader(mediaKitStream));
    } catch(IOException e) {
        System.out.println("Error opening file " +
                           mediaKitsToc.getPath() + ".");
        return(mkList);
    }
    while (!done) {
      try {
        String line = mediaKit.readLine();
        if (line==null)
          done = true;
        else {
          line = line.substring(line.indexOf(' ')).trim();
          line = line.substring(line.indexOf(' ')).trim();
          mkList.addElement(line);
          if (Def.DEBUG) System.out.println("getMediaKitList: line="+line);
          }
      } catch (IOException ex) {
        done = true;
        System.err.println("Error reading file " +
                           mediaKitsToc.getPath() + ".");
      }
    }
    try {
        mediaKitStream.close();
    } catch(IOException e) {
    }
    return mkList;
  }


  /*
   * get list of os's on cd0 cd
   */
  public Vector getOSList()
  {
    String osTocPath = ProfileConstants.osToc;
    Vector osList = new Vector();
    File osTocFile = new File(osTocPath);
    if (! osTocFile.exists()) return(osList);

    boolean done = false;
    BufferedReader osToc;
    FileInputStream osTocStream;

    try {
        osTocStream = new FileInputStream(osTocFile);
        osToc = new BufferedReader(new InputStreamReader(osTocStream));
    } catch(IOException e) {
        System.out.println("Error opening file " +
                           osTocFile.getPath() +
                           ".");
        return(osList);
    }
    while (!done) {
      try {
        String line = osToc.readLine();
        if (line==null)
          done = true;
        else {
          if (Def.DEBUG)System.out.println("getOSList: line="+line);
          line = line.substring(line.indexOf(' ')).trim();
          osList.addElement(line);
          }
      } catch (IOException ex) {
        done = true;
        System.err.println("Error reading file " +
                           osTocFile.getPath() + ".");
      }
    }
    try {
        osTocStream.close();
    } catch(IOException e) {
    }

    return osList;
  }


  /*
   * if upgrade flag set, calls script to grep through installed 
   * pkginfo files in /a/var/sadm/pkg/* for SUNW_LOC to obtain
   * installed locales.
   */
  public void grepInstalledLocales()
  {
    Boolean notUpgrade = 
           (Boolean)wizardState.getData("SolarisInstallNotUpgradeable");
    if (notUpgrade.booleanValue()) 
      return;

    String cmd;
    Process p;
    String[] envp = new String[2];
    envp[0] = "LANG=C";
    envp[1] = "LC_ALL=C";
    cmd = "/sbin/grepInstalledLocales " +ProfileConstants.installedLocFile;
    if (Def.DEBUG)System.out.println("==>grepInstalledLocales cmd: " + cmd );
    try {
        p = Runtime.getRuntime().exec(cmd, envp);
        p.waitFor();
        dispose(p);
    } catch (IOException ex) {
        System.err.println(ex);
     
    } catch (InterruptedException iex) {
      System.err.println(iex);
    }
  }


  /*
   * get list of already installed locales, stored in
   * /tmp/installed_locales.out 
   */
  public Vector getInstalledLocales()
  {
    String installedLocPath = ProfileConstants.installedLocFile;
    Vector locales = new Vector();
    File localesFile = new File(installedLocPath);
    if (! localesFile.exists()) return(locales);

    boolean done = false;
    BufferedReader localeRdr;
    FileInputStream localesStream;

    try {
        localesStream = new FileInputStream(localesFile);
        localeRdr = new BufferedReader(new InputStreamReader(localesStream));
    } catch(IOException e) {
        System.out.println("Error opening file " +
                           localesFile.getPath() +
                           ".");
        return(locales);
    }

    try {
      String line;
      while ((line = localeRdr.readLine()) != null) {
        locales.addElement(line.trim());
      }
    } catch (IOException ex) {
        System.err.println("Error reading file " + installedLocPath + ".");
    }

    try {
        localesStream.close();
    } catch(IOException e) {
    }
    return locales;

  }

  public String calcOSDir(String osName)
  {
    return ProfileUtil.calcOSDir(osName);
  }

  public String getNameOSCD(String osName)
  {
    String osdir = ProfileUtil.calcOSDir(osName);
    String cdNamePath = osdir + ProfileConstants.cdName;
    File cdNameFile = new File(cdNamePath);
    if (cdNameFile.exists()){
      return(readInText(cdNamePath));
    } else {
      return(osName);
    }
  }


  public void setProfileCluster(String cluster)
  {
    ProfileUtil.getProfile().setCluster(cluster);
  }

  public void setProfile64Bit(Boolean value) {
    Profile p = ProfileUtil.getProfile();
    if (value.booleanValue())
      p.setIsabits("64");
    else
      p.setIsabits("32");
  }

  public String getProfileCluster()
  {
    return ProfileUtil.getProfile().getCluster();
  }


  public Vector getProfileUtilSelectedProdList()
  {
    return ProfileUtil.getSelectedProdList();
  }

  public Vector getProfileUtilProductList()
  {
    return ProfileUtil.getProductList();
  }

  public Vector getProfileUtilLocaleList(String locfile)
  {
    return(ProfileUtil.loadLocaleList(locfile));
  }


  public void setProductState(String prodName, String cdName, Boolean state) 
  {
    Vector productList = ProfileUtil.getProductList();
    Enumeration e = productList.elements();
    while (e.hasMoreElements()) {
      SolarisProduct prod2 = (SolarisProduct)e.nextElement();
      if (prodName.equals(prod2.getName()) &&
                       cdName.equals(prod2.getCDname())) {
        prod2.setState(state.booleanValue());
        if (Def.DEBUG) System.out.println("Setting " + prodName + " on " 
                                   + cdName + " to "+state.booleanValue());
      }
    }
  }

  public void saveProfileChanges() 
  {
    ProfileUtil.getProfile().applyChanges();
    ProfileUtil.updateList();
    ProfileUtil.resetFSInfo();
  }


  public void setNewCluster(String currentCluster, String newCluster) {
    Vector productList = ProfileUtil.getProductList();
    SolarisProduct savep = null;
    for (int i=0; i < productList.size(); i++) {
      SolarisProduct p = (SolarisProduct)productList.elementAt(i);
      if (p.file.startsWith(ProfileConstants.osFilePrefix)) {
        if (p.cluster.equals(newCluster)) {
           savep = (SolarisProduct) productList.elementAt(i);
        }
      }
      if ((p.cluster != null) && p.cluster.equals(currentCluster)) {
        p.remove();
      }
    }
    if (savep != null) savep.add();
    setProfileCluster(newCluster);

  }

  public void setProfileLocales(Vector newLocales) {
    Profile profile = ProfileUtil.getProfile();
    profile.setLocales(newLocales);
  }


  public void setSolarisProductLocales(Vector newLocales) 
  {
    Vector productList = ProfileUtil.getProductList();
    if (Def.DEBUG) {
      System.out.print("\nSetting locales to: ");
      for (int k=0; k < newLocales.size(); k++ )
        System.out.print((String)newLocales.elementAt(k) + " ");
      System.out.println();
    }

    for (int i=0; i < productList.size(); i++) {
      SolarisProduct prod = (SolarisProduct)productList.elementAt(i);
      prod.setLocales(newLocales);
      if (Def.DEBUG) {
        System.out.println("for: "+prod.getName() + " on: " + prod.getCDname());
      }
    }

  }

  public void setProfileInstallType(Boolean initialInstall) {
    if (Def.DEBUG) System.out.println("setProfileInstallType("+initialInstall+")");
    Profile profile = ProfileUtil.getProfile();
    profile.setInstallType(initialInstall.booleanValue());
  }

  public void setProfileBackupMedia() {
    String type = (String) wizardState.getData("backupType");
    String path =  (String) wizardState.getData("backupPath");
    Profile profile = ProfileUtil.getProfile();
    profile.setBackupMedia(type, path);
  }

  public Boolean testProfile() {
    Profile profile = ProfileUtil.getProfile();
    return (new Boolean(profile.createDefaultProfile()));
  }

  public Boolean verifyBackupMedia() {
    String path = (String) wizardState.getData("backupPath");
    String type = (String) wizardState.getData("backupType");
    Boolean result = new Boolean(true);
    if (type.equals("local_tape")) {
      // check tape
      result = checkBackupLocalTape(path);
    } else if (type.equals("local_diskette")) {
      // check floppy
      result = new Boolean(true);
    } else if (type.equals("local_filesystem")) {
      // check disk
      result = checkBackupFilesystem(path, "ufs");
    } else if (type.equals("remote_filesystem")) {
      // check NFS mounted file
      result = checkBackupFilesystem(path, "nfs");
    } else if (type.equals("remote_system")) {
      // check remote system
      result = new Boolean(true);
    } else if (type.equals("none")) {
      // no backup media
      result = new Boolean(true);
    } else {
      // unknown device
      result = new Boolean(false);
    }
    
    return result;
  }


  /*
   * doesFileExist
   *
   *   Return Boolean(true) if file exists, false otherwise
   */
  public Boolean doesFileExist(String path) 
  {
    File file = new File(path);

    Boolean status=null;

    if (file.exists()) {
      if (Def.DEBUG) System.out.println("file: " + path + " exists");
      status = new Boolean(true);
    } else {
      if (Def.DEBUG) System.out.println("file: " + path + " does not exist");
      status = new Boolean(false);
    }

    return(status);
  }


  /*
   * wsrFileScan  
   *
   * Look for Web Start Ready files in the specified directory.
   *
   * If found, store their WSR files in products data structure. 
   *
   * Return Boolean(true) if WSR files found & stored, false otherwise.
   */

  public Boolean wsrFileScan(String srcDir, int mediaSource) 
  {
    Boolean status=new Boolean(false);

    if (Def.DEBUG) {
      System.out.println("begin wsrFileScan: " + srcDir + "," + mediaSource);
    }

    /*
     * Validate wsrFileScan input: srcDir and mediaSource 
     */

    if (srcDir == null) return(status);

    if (mediaSource < 0 || 
	mediaSource > CDNode.LAST_SOURCE) return(status); 

    File src = new File(srcDir);

    if (!src.exists() || !src.isDirectory()) {
       if (Def.DEBUG) System.out.println ("directory " + srcDir + "not found");
       return(status);
    }

    String[] files = src.list();
    Vector wsrDirs = new Vector();

    for (int i=0; i < files.length; i++) {
        String dirName = files[i].trim();
	File dir = new File(srcDir + File.separator + dirName);

        if ( dir.isDirectory() ) {
           wsrDirs.addElement(dirName);
        }
    }

    if ( wsrDirs.size() == 0 ) {
       if (Def.DEBUG) System.out.println("No wsr directories found: " + srcDir);
       return(status);
    }

    /*
     * Import the wsr data
     */

    for (int i=0; i < wsrDirs.size(); i++) { 
	String topDir = srcDir + File.separator + wsrDirs.elementAt(i);

	Integer result = importWSR(topDir);

	if (result.intValue() == 0) {

	    /*
	     * Successfull WSR wizard data import.
	     * Set good status & store the media source.  
	     */

	    status = new Boolean(true);

	    String cdName = readFileLine(topDir + ProfileConstants.wsrCDName);

	    String cdsDirPath = ProfileConstants.CDsBaseDir + 
				File.separator + 
				cdName;

	    writeStringToFile(cdsDirPath + ProfileConstants.addSource,
				String.valueOf(mediaSource));

            if (Def.DEBUG) { 
      		System.out.println("good wsrFileScan");
		System.out.println("cds entry = " + cdName);
		System.out.println("media code = " + mediaSource);
	    }
	}
    }

    return(status);
  }


  /*
   * Given a Web Start Ready source directory (from a CD or other file system),
   * copy its contents into the Web Start products area.
   */ 

  public Integer importWSR(String topDir) {

    /*
     * Verify WSR source exists 
     */

    String wsrDir = topDir + ProfileConstants.wsrDir;

    File file = new File(wsrDir);

    if (!file.exists()) {
      System.out.println("importWSR: " + wsrDir + " does not exist");
      return(new Integer(1));
    }

    /*
     * Make sure all files are present
     */

    Vector keyFiles = new Vector();

    String mediaTocSrc = topDir + ProfileConstants.wsrMediaToc; 
    keyFiles.addElement(mediaTocSrc);

    String cdNamePath = topDir + ProfileConstants.wsrCDName;
    keyFiles.addElement(cdNamePath);

    String cdInfoSrc = topDir + ProfileConstants.wsrCDInfo; 
    keyFiles.addElement(cdInfoSrc);

    String productTocSrc = topDir + ProfileConstants.wsrProductToc; 
    keyFiles.addElement(productTocSrc);

    for (int i=0; i < keyFiles.size(); i++) {
      if (! doesFileExist((String)keyFiles.elementAt(i)).booleanValue()) {
        System.out.println("importWSR: " + keyFiles.elementAt(i) + 
                           " does not exist.");
        return(new Integer(2));
      }
    }

    /*
     * Check for empty WSR media_kit.toc and/or product.toc files
     */

    //String mediaTocSrc = topDir + ProfileConstants.wsrMediaToc; 

    String mediaTocDst = ProfileUtil.getMediaKitDir() + 
			 ProfileConstants.mediaKitToc;


    String mediaKitEntry = readFileLine(mediaTocSrc);
    if (mediaKitEntry == null) {
      System.out.println("importWSR: " + mediaTocSrc + " is empty");
      return(new Integer(3));
    }


    String firstProdTocLine = readFileLine(productTocSrc);
    if (firstProdTocLine == null) {
      System.out.println("importWSR: " + productTocSrc + " is empty");
      return(new Integer(4));
    }

    
    /*
     * Get CD's subdir name
     */

    //String cdNamePath = topDir + ProfileConstants.wsrCDName;
   
    String cdNameDir = readFileLine(cdNamePath);

    if (cdNameDir == null) {
      System.out.println("importWSR: could not read" + cdNamePath);
      return(new Integer(5));
    }

    /*
     * Make sure the cd subdir name matches the one in media_kit.toc
     */

    String subdir=mediaKitEntry.substring(0,mediaKitEntry.indexOf(" ")).trim();
    if (! cdNameDir.equals(subdir) ) {
      System.out.println("importWSR: contents of cd.name: " + cdNameDir + 
                        " does not match " + subdir + " in " + mediaTocSrc);
      return(new Integer(6));
    }


    /*
     * Verify CD_NAME in cd.info matches cd name in media_kit.toc
     */

    //String cdInfoSrc = topDir + ProfileConstants.wsrCDInfo; 

    String mediaKitCDName = 
            mediaKitEntry.substring(mediaKitEntry.indexOf(" ")).trim();
    mediaKitCDName = "CD_NAME=" + mediaKitCDName;

    String cdInfoString = readInText(cdInfoSrc);

    if ( cdInfoString.indexOf(mediaKitCDName) == -1 ) {
      System.out.println("importWSR: Didn't find expected entry: " + 
                         mediaKitCDName + "  in " + cdInfoSrc);
      return(new Integer(7));
    }


    /*
     * Verify there is an installer command in cd.info file
     */
    if ( cdInfoString.indexOf("CD_INSTALLER=") == -1 ) {
      System.out.println("importWSR: Didn't find entry for CD_INSTALLER in " 
                         + cdInfoSrc);
      return(new Integer(8));
    }


    /*
     * Make sure we aren't adding duplicate CD
     */

    if (dupTocEntryExists(mediaTocDst, mediaKitEntry)) {
      System.out.println("importWSR: Ignoring attempt to add entry: "+
                          mediaKitEntry + " to " + mediaTocDst +
                          " due to duplicate subdir and/or CD name.");
      return(new Integer(0));
    }
 
    /*
     * Basic error checking done, ok to make actual changes now.
     */


    /*
     * Merge disk media kit from WSR source to disk 
     */

    Vector source = new Vector();
    source.addElement(mediaTocSrc);

    if (!concatFiles(source, mediaTocDst)) {
      System.out.println("importWSR: could not merge " + 
			   mediaTocSrc + " into " + mediaTocDst);
      return(new Integer(9));
    }


    /*
     * Create products/cds area 
     */

    String cdsDirPath = ProfileConstants.CDsBaseDir + "/" + cdNameDir;
    File cdsDirFile = new File(cdsDirPath); 

    if (!cdsDirFile.exists()) {
      cdsDirFile.mkdirs();
    }

    /*
     * Create cd.info file
     */

    //String cdInfoSrc = topDir + ProfileConstants.wsrCDInfo; 
  
    String cdInfoDest = cdsDirPath + ProfileConstants.cdInfo;

    if (!copyFile(cdInfoSrc, cdInfoDest)) {
      System.out.println("importWSR: could not copy " + 
			   cdInfoSrc + " to " + cdInfoDest);
      return(new Integer(10));
    }

    /*
     * Create product.toc file
     */
    
    //String productTocSrc = topDir + ProfileConstants.wsrProductToc; 

    String productTocDest = cdsDirPath + ProfileConstants.productToc;

    if (!copyFile(productTocSrc, productTocDest)) {
      System.out.println("importWSR: could not copy " + 
			   productTocSrc + " to " + productTocDest);
      return(new Integer(11));
    }

    /*
     * Copy CD level help files
     */

    String helpSrc = topDir + ProfileConstants.wsrHelp; 
    String helpDest = ProfileConstants.CDsBaseDir + ProfileConstants.helpBase;

    File src = new File(helpSrc);

    if (src.exists() && src.isDirectory()) {
      if (!copyDir(helpSrc, helpDest)) {
        return(new Integer(12));
      }
    }

    /*
     * Copy pd_files directory
     */

    String destDirPath = ProfileConstants.pdfilesBaseDir;
    String srcDirPath = topDir + ProfileConstants.wsrPDFiles;

    if (!copyDir(srcDirPath, destDirPath)) {
      return(new Integer(13));
    }


    /*
     * WSR import was a success
     * Add to Products List.
     * Clear "noMedia" flag so Product select panel can be used.
     */

    addCDProducts(productTocDest,Boolean.TRUE);

    wizardState.setData(ProfileConstants.noMedia, Boolean.FALSE);

    return(new Integer(0));
  }


  /*
   * Read the addPath from the file saved when products were
   * added via the Add Panel. If addPath file does not exist,
   * which would be the case if product was in original tables,
   * return null.
   */
  public String readCDpath(String cdname) 
  {
    String addPath = null;
    String cdinfoPath = getCDinfoFromCDName(cdname);
    String cdPath = cdinfoPath.substring(0,
                           cdinfoPath.indexOf(ProfileConstants.cdInfo));
    File addPathFile = new File(cdPath + ProfileConstants.addPath);
    if (addPathFile.exists()) {
      addPath = readFileLine(cdPath + ProfileConstants.addPath);
    }
    return(addPath);
  }


  /*
   * Read the addSource (Integer corresponding to CD, File System, Kiosk)
   * that was saved when products were added via the Add Panel.
   * Return CD as default.
   */
  public Integer readCDsource(String cdname) 
  {
    String cdinfoPath = getCDinfoFromCDName(cdname);
    String cdPath = cdinfoPath.substring(0,
                           cdinfoPath.indexOf(ProfileConstants.cdInfo));

    Integer source = new Integer(CDNode.CD);

    File sourceFile = new File(cdPath + ProfileConstants.addSource);

    if (sourceFile.exists()) {
      String addSource = readFileLine(cdPath + ProfileConstants.addSource);
      try {
        source = Integer.valueOf(addSource);
      } catch (NumberFormatException nfe) {
      }
    }

    return(source);
  }


  /*
   * Write string to a file
   */
  public void writeStringToFile(String filePath, String text) 
  {
   try {
      FileWriter addpath = new FileWriter(filePath);
      PrintWriter addpathfile = new PrintWriter(addpath);
      addpathfile.println(text);
      addpathfile.close();
    } catch (IOException ex) {
        System.out.println("writeFileLine IOException: " + ex);
    }

  }


  public static Vector getAllLocalesbyID(String id)
  {
    String locfile = "/tmp/"+id+"locales.out";
    Vector locales = ProfileUtil.loadLocaleList(locfile);
    /*
     * convert the vector of locale to vector of locale id
     */
    Vector localeIDs = new Vector();
    for (int i=0; i<locales.size(); i++)  {
        localeIDs.addElement(((MyLocale)locales.elementAt(i)).getID());
    }

    return(localeIDs);
  }


  /*
   * return a vector containing all unique values from locales'
   * locale_maps
   */
  public static Vector getValuesFromAllLocaleMaps(Vector locales)
  {
    Vector allLocales = new Vector();

    for (int i = 0; i < locales.size(); i++) {
      Vector mapLocales = getValuesFromLocaleMap((String)locales.elementAt(i));
      for (int k = 0; k < mapLocales.size(); k++) {
        String maploc = (String)mapLocales.elementAt(k);
        if ( ! allLocales.contains(maploc))
          allLocales.addElement(mapLocales.elementAt(k));
      }
    }
    return(allLocales);

  }


  /*
   * return a vector containing all unique values from loc's locale_map
   */
  public static Vector getValuesFromLocaleMap(String loc)
  {
    Vector mapLocales = new Vector();
    String dotLocaleDir = ProfileConstants.dotLocaleDir;
    String localedir = readInText(dotLocaleDir);
    String map = localedir + "/" + loc + "/locale_map";

    File localemapFile = new File(map);
    if ( ! localemapFile.exists()) {
      if (Def.DEBUG) System.out.println("getValuesFromLocaleMap: locale_map "
                      + "for " + loc + " does not exist");
      return(mapLocales);
    }

    BufferedReader localemap;
    FileInputStream locMapStream;
    boolean done = false;

    try {
        locMapStream = new FileInputStream(localemapFile);
        localemap = new BufferedReader(new InputStreamReader(locMapStream));
    } catch(IOException e) {
        System.out.println("Error opening file " + localemapFile.getPath() +
                           ".");
        return(mapLocales);
    }

    while(!done) {
      try {
        String line = localemap.readLine();
        if (line == null) {
          done = true;
        } else {
          /*
           * Get locale values from locale_map
           *
           * The lines are in the form:
           *      ATTRIBUTE=locale
           */
          int equalsPosition = line.indexOf('=');
          if (equalsPosition > 0) {
            String value = (line.substring(equalsPosition+1)).trim();
            if ( ! mapLocales.contains(value)) {
              mapLocales.addElement(value);
              if (Def.DEBUG) System.out.println("getAllLocalesbyID: adding "
                                            + "value=" + value);
            }
          }
        }
      } catch(IOException e) {
        done = true;
        System.out.println("Error reading file " +
                                localemapFile.getPath() + ".");
      }
    }
    try {
        locMapStream.close();
    } catch(IOException e) {

    }
   
    return(mapLocales);
  }

  /*
   * getMiniRootLocale
   *
   * get the locale of the miniroot from locale cmd
   */
  public static String getMiniRootLocale()
  {
    String lcmessages = null;
    String line;
    Process p;
    String cmd = "/usr/bin/locale";
    try {
        p = Runtime.getRuntime().exec(cmd);
        BufferedReader cmdOutput =
          new BufferedReader(new InputStreamReader(
                         new BufferedInputStream(p.getInputStream())));
        while (((line = cmdOutput.readLine()) != null)) {
          if ((line.startsWith("LC_MESSAGES=")) && 
             (line.length() > "LC_MESSAGES=".length() )) {
            lcmessages=line.substring(line.indexOf("=")+1);
            if (lcmessages.startsWith("\"")){
               lcmessages = lcmessages.substring(1,lcmessages.length()-1);
            }
          }
        }
        p.waitFor();
        try {
            p.getInputStream().close();
            p.getOutputStream().close();
            p.getErrorStream().close();
            p.destroy();
        } catch (IOException ex) {
            p.destroy();
        }

    } catch (IOException ex) {
        System.err.println(ex);

    } catch (InterruptedException iex) {
      System.err.println(iex);
    }
    return(lcmessages);
  }

  /*
   * duplicateTocEntryExists
   *
   */
  public boolean dupTocEntryExists(String path, String newText) 
  {
    String line = null;
    BufferedReader text;
    FileInputStream textFileStream;

    String newCDname = newText.substring(newText.indexOf(" ")).trim();
    String newSubdir = newText.substring(0,newText.indexOf(" ")).trim();  

    /*
     * Open the text file.
     */
    File textFile = new File(path);
    try {
      textFileStream = new FileInputStream(textFile);
      text = new BufferedReader(new InputStreamReader(textFileStream));
    } catch(IOException e) {
      System.out.println("Error opening file " + textFile.getPath() + ".");
      return(false);
    }

    /*
     * Read the contents
     * 
     * Check for matches of the subdir and CD Name individually.
     */
    try {
      while ((line = text.readLine()) != null) {
        String subdir = line.substring(0,line.indexOf(" ")).trim();  
        String cdname = line.substring(line.indexOf(" ")).trim();
        if (subdir.equals(newSubdir)) {
          if (Def.DEBUG)System.out.println("dupTocEntryExists: " +
                             newSubdir + " already in " + line);
          return (true);
        }
        if (cdname.equals(newCDname)) {
          if (Def.DEBUG)System.out.println("dupTocEntryExists: " +
                             newCDname + " already in " + line);
          return (true);
        }
        
      }
    } catch (IOException ex) {
        System.out.println("dupTocEntryExists Error reading file "
                              +textFile.getPath() + ".");
    }
    try {
       textFileStream.close();
    } catch(IOException e) {

    }

    return (false);
  }


  /*
   * readInText
   *
   *   Reads contents of file found in "path" 
   *   and returns contents as String
   */
  public static String readInText(String path) 
  {
    String buffer = null;
    String line = null;
      boolean isFirstLine = true;
      BufferedReader text;
      FileInputStream textFileStream;

      /*
       * Open the text file.
       */
      File textFile = new File(path);
      try
        {
          textFileStream = new FileInputStream(textFile);
          text = new BufferedReader(new InputStreamReader(textFileStream));
        }
      catch(IOException e)
        {
          System.out.println("Error opening file " + textFile.getPath() + ".");
          return("");
        }

      /*
       * Read the contents
       */
      try {
        while ((line = text.readLine()) != null) {
          if (isFirstLine == true) {
            buffer=line;
            isFirstLine = false;
          } else {
            buffer = buffer + " " + line;
          }
        }
      } catch (IOException ex) {
        System.out.println("Error reading file "+textFile.getPath() + ".");
      }
      try {
         textFileStream.close();
      } catch(IOException e) {

      }

    if (buffer == null) return ("");
    return (buffer);
  }


  /*
   * Saves copack selections in product_table
   */
  public void saveSelection(Vector sel) 
  {
    Vector selection = sel;

    /*
     * Delete product_table if one exists 
     */
    File productTable = new File(ProfileConstants.productTable);
    if (productTable.exists()) {
      productTable.delete();
      if (Def.DEBUG) System.out.println("Found product_table, deleting");
    }

    /*
     * Don't write a product_table if no products selected
     */
    if (sel.size() == 0) return;
    String cdNameSuffix = "CDName";
    String WSRSuffix = "WSR";
    String launchSuffix = "LaunchCommand";
    String imageDirSuffix = "IMAGEDIR";
    String volIDSuffix = "VOLID";
    String keyfileSuffix = "KEYFILE";
    String miniRootOptsSuffix = "MiniRootOpts";
    String miniRootOptsDeflt = "-R /a";
    String cdNum = null;
    String cdName = null;
    Vector locales = null;

    /*
     * Look through the entries and add additional 
     * attributes from the product directory structure.
     * Assumes selection is ordered by cd, with CDName
     * entry first for that CD.
     */
    try {
      FileWriter log = new FileWriter(ProfileConstants.productTable);
      PrintWriter propfile = new PrintWriter(log);
      for (int i=0; i< sel.size(); i++) {
        if (Def.DEBUG) System.out.println(selection.elementAt(i));
        String entry = (String) selection.elementAt(i);
        propfile.println(entry);
        /*
         * See if this is a CDName entry
         */
        int cdindex = entry.indexOf(cdNameSuffix);
        if ( cdindex != -1) {
          cdNum = entry.substring(0,cdindex-1);
          cdName = entry.substring(cdindex+cdNameSuffix.length()+1);

         /*
          * Read the CDs directory structure to obtain installer info,
          * etc.
          */
          String cdInfo = getCDinfoFromCDName(cdName);
          if (Def.DEBUG) {
            System.out.println("ProfileServer saveSelection: cdName="+cdName);
            System.out.println("ProfileServer saveSelection: cdInfo="+cdInfo);
          }
          Hashtable cdhash = getCDinfo(cdInfo);

         /*
          * Read the value of INSTALLER_WSR. If WSR is NO, we don't
          * want to save SDK specific attributes in the dispatch table.
          */
          String INSTALLER_WSR = (String) cdhash.get("INSTALLER_WSR");
          if ((INSTALLER_WSR == null) || (! INSTALLER_WSR.equals("NO"))) {
            propfile.println(cdNum + "." + WSRSuffix + "=YES");
          } else {
            propfile.println(cdNum + "." + WSRSuffix + "=NO");
          }

          String value = (String) cdhash.get("CD_VOLID");
          if (value != null) 
            propfile.println(cdNum + "." + volIDSuffix + "=" + value);

          value = (String) cdhash.get("IMAGEDIR");
          if (value != null) 
            propfile.println(cdNum + "." + imageDirSuffix + "=" + value);

          value = (String) cdhash.get("CD_KEYFILE");
          if (value != null) 
            propfile.println(cdNum + "." + keyfileSuffix + "=" + value);
                   
          value = (String) cdhash.get("CD_INSTALLER");
          if (value != null) {
            /*
             * Now see if we need to add a -locales onto the command
             */
            if ((INSTALLER_WSR == null) || (! INSTALLER_WSR.equals("NO"))) {
              locales = 
                 (Vector)wizardState.getData(InstallConstants.selectedLocales);
              int localesSize = 0;
              if (locales != null) localesSize = locales.size();
              if (localesSize != 0) {
                String locstring = (String) locales.firstElement();
                for (int k=1; k < localesSize; k++) {
                   locstring += "," + locales.elementAt(k);
                }
	        locstring = "en," + locstring;
                if (Def.DEBUG) {
                  System.out.println("adding -locales " + locstring);
                }
                value += " -locales " + locstring;
              } 
            }
            propfile.println(cdNum + "." + launchSuffix + "=" + value);
          }

          value = (String) cdhash.get("MINIROOT_OPTS");
          if (value != null) {
              propfile.println(cdNum + "." + miniRootOptsSuffix + "=" + value);
          } else {
             if ((INSTALLER_WSR == null) || (! INSTALLER_WSR.equals("NO"))) 
                propfile.println(cdNum + "." + miniRootOptsSuffix + "=" + 
                                                          miniRootOptsDeflt);
          }
        } 
      }
      propfile.close();
    } catch (IOException ex) {
        System.out.println("saveSelection IOException: " + ex);
    }

  }

  /*
   * Creates the dispatch_table from the lang_table and/or the
   *    product_table
   */
  public void createDispatchTable() 
  {
    boolean haveLangs = false;
    boolean haveProducts = false;
    boolean haveCD2 = false;
    int startFrom = 1;

    /*
     * Create /a/var/sadm/webstart 
     */
    File aVarSadmWebstart = new File (ProfileConstants.aVarSadmWebstart);
    if (! aVarSadmWebstart.exists()) {
      if (Def.DEBUG) System.out.println("createDispatchTable: creating " 
                       + ProfileConstants.aVarSadmWebstart);
      aVarSadmWebstart.mkdirs();

    }

    /*
     * Delete dispatch_table if one exists 
     */
    File dispatchtable = new File(ProfileConstants.dispatchTable);
    if (dispatchtable.exists()) {
      dispatchtable.delete();
      if (Def.DEBUG) System.out.println("Found dispatch_table, deleting");
    }

    /*
     * Don't create table if install not successful
     */
    File instsuccess = new File (ProfileConstants.instsuccess);
    if (! instsuccess.exists()) {
      if (Def.DEBUG) System.out.println("Returning from create_dispatch_table: "
                       + ProfileConstants.instsuccess + " does not exist");
      return;
    }

    /*
     * Deterimine if we need to install from Virtual CD 2
     */
    File virtual2File = new File(ProfileConstants.AVarSadmSystemData + 
                             File.separator + ProfileConstants.VirtualPkgs2);

    if (virtual2File.exists()) {
      saveCD2_table();
      startFrom++ ;
      haveCD2 = true;
    }

    /*
     * Deterimine if we have lang_table or product_table
     */
    File virtual3File = new File(ProfileConstants.AVarSadmSystemData + 
                             File.separator + ProfileConstants.VirtualPkgs3);

    if (virtual3File.exists()) {
      File langtable = new File(ProfileConstants.langTable);
      if ( langtable.exists()) {
        haveLangs = true;
        if (startFrom != 1) renumberStartingFrom(startFrom, 
                                                 ProfileConstants.langTable);
        startFrom++;
      }
    }

    File producttable = new File(ProfileConstants.productTable);
    if (producttable.exists()) {
      haveProducts = true;
      renumberStartingFrom(startFrom, ProfileConstants.productTable);
    }

    if (! haveLangs && ! haveProducts && ! haveCD2 ) return;

    Vector fileVector = new Vector();

    if ( haveCD2 ) {
      fileVector.addElement(ProfileConstants.cd2Table);
    }

    if ( haveLangs ) {
      fileVector.addElement(ProfileConstants.langTable);
    }

    if ( haveProducts ) {
      fileVector.addElement(ProfileConstants.productTable);
    }
   
    /*
     * Write out the data to the dispatch_table
     */
    concatFiles(fileVector, ProfileConstants.dispatchTable);

   }



  /*
   * Renumbers entries in table starting with startFrom
   */
  public void renumberStartingFrom(int startFrom, String table)
  {

    File tableFile = new File(table);
    if (!tableFile.exists()) {
      System.out.println("ERROR, unable to renumber " + table + 
                   ", does not exist");
      return;
    }

    int newnum = startFrom-1;
    int currentNum = -1;

    BufferedReader tableRdr;
    FileInputStream tableStream;

    try {
       tableStream = new FileInputStream(tableFile);
       tableRdr = new BufferedReader(new InputStreamReader(tableStream));
    } catch(IOException e) {
        System.out.println("ERROR, unable to renumber " + table); 
        System.out.println("Error opening file " + table + ".");
        return;
    }

    Vector newEntries = new Vector();
    try {
      int dot;
      String cdnum;
      String entry = null;
      String rest = null;
      String newEntry = null;

      while ((entry = tableRdr.readLine()) != null) {
        entry = entry.trim();
        dot = entry.indexOf('.');
        if (dot == -1 ) continue;
        cdnum = entry.substring(1,dot);
        rest = entry.substring(dot);
        if (Integer.valueOf(cdnum).intValue() != currentNum) {
          newnum++;
          if (currentNum == -1) {
            currentNum = Integer.valueOf(cdnum).intValue();
          } else {
            currentNum++;
          }
        }
        newEntry = "W" + Integer.toString(newnum, 10) + rest ;
        newEntries.addElement(newEntry);
      }
    } catch (IOException ex) {
        System.err.println("Error reading file " + table + ".");
    }

    try {
      tableStream.close();
    } catch(IOException e) {
    }

    /* 
     * We have all the entries. Now write it out
     */
    try {
      FileWriter log = new FileWriter(table+".new");
      PrintWriter propfile = new PrintWriter(log);
      for (int i=0; i< newEntries.size(); i++) {
        propfile.println(newEntries.elementAt(i));
      }
      propfile.close();
    } catch (IOException ex) {
        System.out.println("renumber Startingfrom IOException: " + ex);
    }

    /* 
     * Now delete the old table and rename the new one
     */
     
    tableFile.delete();
    File newFile = new File(table+".new");
    newFile.renameTo(tableFile);
    if (Def.DEBUG) System.out.println("renumberStartingFrom " + startFrom + 
                                      ": " + table);
  }

  /*
   * Copy one file.  
   */

  public boolean copyFile(String srcPath, String destPath)
  {
     Vector source = new Vector();
     source.addElement(srcPath);

     File destFile = new File(destPath);

     if (destFile.exists()) {
	destFile.delete();
     }

     return(concatFiles(source, destPath));
  }

  /*
   * Copy one direcrtory
   */

  public boolean copyDir(String srcDirPath, String destDirPath)
  {
    /*
     * Create destination directory
     */

    File destDir = new File(destDirPath); 

    if (!destDir.exists()) {
      destDir.mkdirs();
    }

    /*
     * Copy the pd_files
     */

    File srcDir = new File(srcDirPath);

    if (!srcDir.exists()) {
      System.out.println("importWSR: could not read" + srcDirPath);
      return(false);
    }

    String[] files = srcDir.list();

    for (int i=0; i < files.length; i++) { 
      String file = files[i].trim();	

      String srcPath = srcDirPath + "/" + file;
      String destPath = destDirPath + "/" + file;

      File src = new File(srcPath);

      boolean copyStatus;

      if (src.isFile()) {
        copyStatus = copyFile(srcPath, destPath); 
      } else {
        copyStatus = copyDir(srcPath, destPath); 
      }

      if (!copyStatus) {
        System.out.println("importWSR: could not copy " + 
			   srcPath + " to " + destPath);
        return(false);
      }
    }

    return(true);
  }

  /*
   * Concats files together. fileVector should contain absolute
   * pathnames of files.
   */
  public boolean concatFiles(Vector fileVector, String outputfile)
  {
    try {
      FileOutputStream log = new FileOutputStream(outputfile, true);
      DataOutputStream out = new DataOutputStream(log);
      for(int index = 0; index < fileVector.size(); index++) {
         String filename = (String)fileVector.elementAt(index);
         if (Def.DEBUG) System.out.println("concatFiles: adding "
                           + filename + " to " + outputfile);
         RandomAccessFile inFile = new RandomAccessFile(filename, "r");
         byte[] fileBytes = new byte[(int)inFile.length()];
         inFile.readFully(fileBytes);
         inFile.close();
         out.write(fileBytes);
       }
     } catch(IOException e) {
       System.out.println("concatFiles IOException: " + e);
       return(false);
     }

     return(true);
  }


  /*
   * Saves cd2_table
   */
  public void saveCD2_table() 
  {
    /*
     * Delete cd2_table if one exists 
     */
    File cd2table = new File(ProfileConstants.cd2Table);
    if (cd2table.exists()) {
      cd2table.delete();
      if (Def.DEBUG) System.out.println("Found cd2_table, deleting");
    }

    String W1 = "W1.";
    String cdNameSuffix = "CDName";
    String launchSuffix = "LaunchCommand";
    String volIDSuffix = "VOLID";
    String noSkipSuffix = "NO_SKIP";
    String miniRootOptsSuffix = "MiniRootOpts";
    String miniRootOptsDeflt = "-R /a";
    String installcmd = ProfileConstants.CD2installer;
    String CDentry = null;
    String entry = null;
    Vector locales = null;

    /*
     * write out the CDName, VOLID, LaunchCommand, MiniRootOPts, 
     * and Products
     */
    try {
      FileWriter log = new FileWriter(ProfileConstants.cd2Table);
      PrintWriter propfile = new PrintWriter(log);
      if (ProfileConstants.platform.equals("sparc")) {
        CDentry = W1 + cdNameSuffix + "=" + ProfileConstants.CD2sparcName;
        entry = W1 + volIDSuffix + "=" + ProfileConstants.CD2volIDsparc;
      } else {
        CDentry = W1 + cdNameSuffix + "=" + ProfileConstants.CD2iaName;
        entry = W1 + volIDSuffix + "=" + ProfileConstants.CD2volIDia;
      }
      propfile.println(CDentry);
      propfile.println(entry);

      /*
       * add the install command with -warp ,Summary and -locales option
       */
      installcmd += " -warp ,Summary";

      locales = 
          (Vector)wizardState.getData(InstallConstants.selectedLocales);
      int localesSize = 0;
      if (locales != null) localesSize = locales.size();
      if (localesSize != 0) {
        String locstring = (String) locales.firstElement();
        for (int k=1; k < localesSize; k++) {
          locstring += "," + locales.elementAt(k);
        }

        if (Def.DEBUG) {
          System.out.println("saveCD2_table: adding -locales " + locstring);
        }
        installcmd += " -locales " + locstring;
      } 
      propfile.println(W1 + launchSuffix + "=" + installcmd);
      propfile.println(W1 + miniRootOptsSuffix + "=" + miniRootOptsDeflt);
      propfile.println(W1 + "Product1.MiniRoot=YES" );
      
      /*
       * Tell launcher to disable skip and exit buttons
       */
      //propfile.println(W1 + noSkipSuffix + "=YES");

      propfile.close();
    } catch (IOException ex) {
        System.out.println("saveCD2_table IOException: " + ex);
    }

  }


  /*
   * Saves lang selections in lang_table
   */
  public void saveLangTable(Vector langData) 
  {
    /*
     * Delete lang_table if one exists 
     */
    File langtable = new File(ProfileConstants.langTable);
    if (langtable.exists()) {
      langtable.delete();
      if (Def.DEBUG) System.out.println("Found lang_table, deleting");
    }

    /*
     * Don't write a lang_table if domestic cd0
     */
    File domDocPDfile = new File (ProfileConstants.domesticDocPDfile);
    if (domDocPDfile.exists()) {
      if (Def.DEBUG) System.out.println("Domestic CD0, not writing lang_table");
      return;
    }
   
    /*
     * Don't write a lang_table if no locales selected
     */
    if (langData.size() == 0) return;

    String W1 = "W1.";
    String cdNameSuffix = "CDName";
    String launchSuffix = "LaunchCommand";
    String volIDSuffix = "VOLID";
    String miniRootOptsSuffix = "MiniRootOpts";
    String miniRootOptsDeflt = "-R /a";
    String installcmd = ProfileConstants.LangCDinstaller;
    String CDentry = null;
    String entry = null;
    Vector locales = null;

    /*
     * write out the CDName, VOLID, LaunchCommand, MiniRootOPts, 
     * and Products
     */
    try {
      FileWriter log = new FileWriter(ProfileConstants.langTable);
      PrintWriter propfile = new PrintWriter(log);
      if (ProfileConstants.platform.equals("sparc")) {
        CDentry = W1 + cdNameSuffix + "=" + ProfileConstants.LangCDsparcName;
        entry = W1 + volIDSuffix + "=" + ProfileConstants.LangCDvolIDsparc;
      } else {
        CDentry = W1 + cdNameSuffix + "=" + ProfileConstants.LangCDiaName;
        entry = W1 + volIDSuffix + "=" + ProfileConstants.LangCDvolIDia;
      }
      propfile.println(CDentry);
      propfile.println(entry);

      /*
       * add the install command with -warp Verify,Summary and -locales option
       */
      locales = 
          (Vector)wizardState.getData(InstallConstants.selectedLocales);
      int localesSize = 0;
      if (locales != null) localesSize = locales.size();
      if (localesSize != 0) {
        String locstring = (String) locales.firstElement();
        for (int k=1; k < localesSize; k++) {
          locstring += "," + locales.elementAt(k);
        }

        if (Def.DEBUG) {
          System.out.println("saveLangTable: adding -locales " + locstring);
        }
        installcmd += " -warp Verify,Summary";
        installcmd += " -locales " + locstring;
      } 
      propfile.println(W1 + launchSuffix + "=" + installcmd);

      propfile.println(W1 + miniRootOptsSuffix + "=" + miniRootOptsDeflt);

      /*
       * Now add the selected languages as products (passed in)
       */
      for (int i=0; i< langData.size(); i++) {
        if (Def.DEBUG) System.out.println("saveLangTable: " + langData.elementAt(i));
        propfile.println(langData.elementAt(i));
      } 
      propfile.close();
    } catch (IOException ex) {
        System.out.println("saveLangTable IOException: " + ex);
    }

  }

  /*
   * Read the geo file and save in wizard state
   */
  public void readGeoFile() 
  {
    Vector geoVec = new Vector();
    String dotLocaleDir = ProfileConstants.dotLocaleDir;
    String localedir = readInText(dotLocaleDir);
    String geo = localedir + "/" +  ProfileConstants.geoFile;

    File geoFile = new File(geo);
    if ( ! geoFile.exists()) {
      if (Def.DEBUG) System.out.println("readGeoFile: " + 
                     localedir + "/" +  ProfileConstants.geoFile
                      + " does not exist");
      return;
    }

    BufferedReader geoReader;
    FileInputStream geoStream;
    boolean done = false;

    try {
        geoStream = new FileInputStream(geoFile);
        geoReader = new BufferedReader(new InputStreamReader(geoStream));
    } catch(IOException e) {
        System.out.println("Error opening file " + geoFile.getPath() +
                           ".");
        return;
    }

    while(!done) {
      try {
        String line = geoReader.readLine();
        if (line == null) {
          done = true;
        } else {
          /*
           * Get geo ids and names from geo file
           *
           * The lines are in the form:
           *      geo_id     Geo Name 
           *
           * Creata a vector withe entries of form:
           *      geo_id;Geo Name
           */
          int equalsPosition = line.indexOf('\t');
          if (equalsPosition > 0) {
            String geoID = line.substring(0,equalsPosition);
            String geoName = (line.substring(equalsPosition+1)).trim();
            String value = geoID + ";" + geoName;
            geoVec.addElement(value);
            if (Def.DEBUG) System.out.println("readGeoFile: adding: " + value);
          }
        }
      } catch(IOException e) {
        done = true;
        System.out.println("Error reading file " +
                                geoFile.getPath() + ".");
      }
    }
    try {
        geoStream.close();
    } catch(IOException e) {

    }
   
    wizardState.setData(ProfileConstants.geoVector, geoVec);
    return;
  }



  private Boolean checkBackupLocalTape(String path) {
    Boolean result = new Boolean(true);
    try {
      String cmd = "mt -f " + path + " status";
      Process p;
      String[] envp = new String[2];
      envp[0] = "LANG=C";
      envp[1] = "LC_ALL=C";
      p = Runtime.getRuntime().exec(cmd, envp);
      p.waitFor();
      if (p.exitValue() == 0) {
	dispose(p);
	result = new Boolean(true);
      } else {
	System.err.println("Could open " + path + ", backup test failed");
        result = new Boolean(false);
      }
    } catch (IOException ex) {
      result = new Boolean(false);
      System.err.println(ex);
    } catch (InterruptedException iex) {
      result = new Boolean(false);
      System.err.println(iex);
    } catch (Exception ex) {
      result = new Boolean(false);
      System.err.println(ex);
    }

    return result;
  }

  private Boolean checkBackupFilesystem(String path, String fstype) {
    Boolean result = new Boolean(true);
    String tmpMntDir = "/tmp/tmpmnt";
    try {
      // make the temp dir
      String cmd = "mkdir " + tmpMntDir;
      Process p;
      String[] envp = new String[2];
      envp[0] = "LANG=C";
      envp[1] = "LC_ALL=C";
      p = Runtime.getRuntime().exec(cmd, envp);
      p.waitFor();
      if (p.exitValue() != 0){
	System.err.println("unable to make directory: " + tmpMntDir);
      }
      // mount the selected disk on the mntpnt
      cmd = "mount -F " + fstype + " -o rw " + path + " " + tmpMntDir;
      envp[0] = "LANG=C";
      p = Runtime.getRuntime().exec(cmd, envp);
      p.waitFor();
      if (p.exitValue() == 0) {
	// mount is successful
	cmd = "touch " + tmpMntDir + "/backuptest";
	p = Runtime.getRuntime().exec(cmd, envp);
	p.waitFor();
	if (p.exitValue() == 0) {
	  cmd = "rm "  + tmpMntDir + "/backuptest";
	  p = Runtime.getRuntime().exec(cmd, envp);
	  result = new Boolean(true);
	} else {
	  System.err.println("Could not write to " + 
			     path + ", backup test failed");
	  result = new Boolean(false);
	}
        // unmount and remove directory
        cmd = "umount -f " + tmpMntDir;
        envp[0] = "LANG=C";
        p = Runtime.getRuntime().exec(cmd, envp);
        p.waitFor();
        cmd = "rmdir " + tmpMntDir;
        envp[0] = "LANG=C";
        p = Runtime.getRuntime().exec(cmd, envp);
        p.waitFor();
      } else
        result = new Boolean(false);
      dispose(p);
    } catch (IOException ex) {
      result = new Boolean(false);
      System.err.println(ex);
    } catch (InterruptedException iex) {
      result = new Boolean(false);
      System.err.println(iex);
    } catch (Exception ex) {
      result = new Boolean(false);
      System.err.println(ex);
    }

    return result;
  }

  /**
    *  Calls method to eject CD (still works if CDdeviceRaw is null)
    */
  public void EjectCD()
  {
    String CDdeviceRaw = 
           (String)wizardState.getData(ProfileConstants.CDdeviceRaw);
    MountCDTask.EjectCD(CDdeviceRaw);
  }

  /**
    *  Calls method to umount and eject CD
    */
  public void UmountEjectCD()
  {
    String CDdeviceRaw =
           (String)wizardState.getData(ProfileConstants.CDdeviceRaw);
    if (Def.DEBUG) System.out.println("UmountEjectCD: cdmount raw=" +
                ProfileConstants.CDmount + " " + CDdeviceRaw);
    MountCDTask.UmountEject(ProfileConstants.CDmount, CDdeviceRaw);
  }

  /**
    * Parses /a/var/sadm/system/data/packages_to_be_added file
    * and puts virtual cd 2 and virtual cd 3 packages in 
    * /a/var/sadm/webstart/virtualpkgs2 and virtualpkgs3 files, 
    * respectively.
    */
  public void parsePackagesToBeAddedFile()
  {
    File instsuccess = new File (ProfileConstants.instsuccess);
    if (! instsuccess.exists()) {
      if (Def.DEBUG) System.out.println("return from parsePackagesToBeAdded: "
                       + ProfileConstants.instsuccess + " does not exist");
      return;
    }

    /*
     * call script to go through the tables
     * Will result in virtualpkgs2 and virtualpkgs3 files being
     * created in /a/var/sadm/webstart (if any files match).
     */
    String cmd;
    Process p;
    String[] envp = new String[2];
    envp[0] = "LANG=C";
    envp[1] = "LC_ALL=C";
    cmd = "/webstart/wizards/bin/parsePackagesToBeAdded";
    if (Def.DEBUG)System.out.println("==>parsePackagesToBeAddedFile cmd: " + cmd );
    try {
        p = Runtime.getRuntime().exec(cmd, envp);
        p.waitFor();
        dispose(p);
    } catch (IOException ex) {
        System.err.println(ex);

    } catch (InterruptedException iex) {
      System.err.println(iex);
    }
  }

  /*
   * Cleans up after an Upgrade Dryrun, until bugid 4232471 has been fixed
   */
  public Boolean CleanAfterUpgradeDryrun()
    {
      String cmd;
      Process p;
      String[] envp = new String[2];
      envp[0] = "LANG=C";
      envp[1] = "LC_ALL=C";
      String line;
      Vector mounts = new Vector();
      Vector swaps = new Vector();
      int size;

      try {
	// Get the /a mounted filesystems
	cmd = "/usr/sbin/df";
	p = Runtime.getRuntime().exec(cmd, envp);
	BufferedReader cmdOutput = 
	  new BufferedReader(new InputStreamReader(new BufferedInputStream(p.getInputStream())));
	while (((line = cmdOutput.readLine()) != null)) {
	  String tkn = new StringTokenizer(line).nextToken();
	  if (tkn.startsWith("/a")) {
	    mounts.addElement(tkn);
	  }
	}
	p.waitFor();
	dispose(p);
	// Get the /a mounted filesystems
	cmd = "/usr/sbin/swap -l";     
	p = Runtime.getRuntime().exec(cmd, envp);
	cmdOutput = 
	  new BufferedReader(new InputStreamReader(new BufferedInputStream(p.getInputStream())));
	// Get the added swap filesystems
	while (((line = cmdOutput.readLine()) != null)) {
	  String tkn = new StringTokenizer(line).nextToken();
	  if (tkn.startsWith("/dev")) {
	    swaps.addElement(tkn);
	  }
	}
	p.waitFor();
	dispose(p);
	// Umount the filesystems
	size = mounts.size();
	if (size > 0) {
	  for (int i=size-1; i>=0; --i){
	    String fs = (String)mounts.elementAt(i);
	    if (Def.DEBUG) System.out.println("unmounting fs: " + fs);
	    cmd = "/sbin/umount" + " " + fs;
	    p = Runtime.getRuntime().exec(cmd, envp);
	    p.waitFor();
	    if (p.exitValue() > 0) {
	      dispose(p);
	      return(Boolean.FALSE);
	    }
	    dispose(p);
	  }
	}
	// delete the swap partitions added
	size = swaps.size();
	if (size > 0) {
	  for (int i=size-1; i>=0; --i) {
	    String swp = (String)swaps.elementAt(i);
	     if (Def.DEBUG) System.out.println("deleting swap: " + swp);
	    cmd = "/usr/sbin/swap -d" + " " + swp;
	    p = Runtime.getRuntime().exec(cmd, envp);
	    p.waitFor();
	    if (p.exitValue() > 0) {
	      dispose(p);
	      return(Boolean.FALSE);
	    }
	    dispose(p);
	  }
	}
      } catch (IOException ex) {
	System.err.println(ex);
	return(Boolean.FALSE);
    } catch (InterruptedException iex) {
      System.err.println(iex);
      return(Boolean.FALSE);
    } catch (Exception ex) {
      System.err.println(ex);
      return(Boolean.FALSE);
    }
    return(Boolean.TRUE);
    }

  public void syncUpgradeProfile()
    {
      String cmd;
      Process p;
      String[] envp = new String[2];
      envp[0] = "LANG=C";
      envp[1] = "LC_ALL=C";
      String tp = ProfileConstants.installDir + "/testProfile";
      String pf = ProfileConstants.installDir + "/profile";
      cmd = "cp " + tp + " " + pf;
      try {
	p = Runtime.getRuntime().exec(cmd, envp);
	p.waitFor();
	dispose(p);
      } catch (IOException ex) {
	System.err.println(ex);
      } catch (InterruptedException iex) {
	System.err.println(iex);
      } catch (Exception ex) {
	System.err.println(ex);
      }
    }
  public Boolean isUpgradeBackupReq()
    {
      Profile profile = ProfileUtil.getProfile();
      return (new Boolean(profile.isBackupReq()));
    }

  public Boolean isThereSwap() {
    Profile profile = ProfileUtil.getProfile();
    Vector plist = profile.getPartitionList(true);
    String swapslice = PartitionInfo.getDefaultSwapSliceNum();
    String swapdisk = PartitionInfo.getDefaultSwapDisk();
    for (int i=0; i < plist.size(); i++) {
      PartitionInfo pinfo = (PartitionInfo) plist.elementAt(i);
      int slicenum = pinfo.getSliceNum();
      String slice = "s"+slicenum;
      if (pinfo.getName().equals("swap") && 
	  pinfo.getDisk().equals(swapdisk) &&
	  slice.equals(swapslice)){
	return (new Boolean(true));
      }
    }
    
    return (new Boolean(false));
  }

  // Search for start location of the swap partition
  public Boolean isSwapAtBeginning() {
    Boolean retval = new Boolean(false);
  
    String swapDisk = PartitionInfo.getDefaultSwapDisk();
    DiskInfo dinfo = ProfileUtil.getDiskInfo();
    int altStart = dinfo.getAltCylStart(swapDisk);
    int altSize = dinfo.getAltCylSize(swapDisk);
    int firstCyl = altStart + altSize;
    int swapStart = PartitionInfo.getSwapStartCyl();
    if (swapStart != firstCyl) {
      retval = new Boolean(false);
    } else {
      retval = new Boolean(true);
    }
    return retval;
  }
  
   public void set64Bit(Profile profile) {
      String arch;
      try {
	FileAgent fc = new FileAgent();
	fc.readOpen(ProfileConstants.installDir+"/uname.out");
	arch = fc.readLine();
	arch = arch.trim();
	if (Def.DEBUG) System.out.println("Arch is " + arch);		
	fc.close();
	fc = null;
      } catch (FileAgentException ex) {
	System.err.println(ex);
	arch = "sun4u";           //Assume sun4u
      }
      
      //System.out.println("Initializing isabits");
      if (arch.equals("i86pc")) {
	wizardState.setData(ProfileConstants.no64, new Boolean(true));
	profile.setIsabits("32");
      } else {
	wizardState.setData(ProfileConstants.no64, new Boolean(false));
	if (arch.startsWith("sun4u")){
	  wizardState.setData(ProfileConstants.SixtyFourBit,
			      new Boolean(true));
	  profile.setIsabits("64");
	} else {
	  wizardState.setData(ProfileConstants.SixtyFourBit,
			      new Boolean(false));
	  profile.setIsabits("32");
	}
      }
    }

 private void dispose(Process p)
    {
      try {
	p.getInputStream().close();
	p.getOutputStream().close();
	p.getErrorStream().close();
	p.destroy();
      } catch (IOException ex) {
	p.destroy();
      }
    }
}

