SolarisRoutines.java :  » IDE-Netbeans » mobility » org » netbeans » modules » mobility » cldcplatform » startup » Java Open Source

Java Open Source » IDE Netbeans » mobility 
mobility » org » netbeans » modules » mobility » cldcplatform » startup » SolarisRoutines.java
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common
 * Development and Distribution License("CDDL") (collectively, the
 * "License"). You may not use this file except in compliance with the
 * License. You can obtain a copy of the License at
 * http://www.netbeans.org/cddl-gplv2.html
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 * specific language governing permissions and limitations under the
 * License.  When distributing the software, include this License Header
 * Notice in each file and include the License file at
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the GPL Version 2 section of the License file that
 * accompanied this code. If applicable, add the following below the
 * License Header, with the fields enclosed by brackets [] replaced by
 * your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * Contributor(s):
 *
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 * Microsystems, Inc. All Rights Reserved.
 *
 * If you wish your version of this file to be governed by only the CDDL
 * or only the GPL Version 2, indicate your decision by adding
 * "[Contributor] elects to include this software in this distribution
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 * single choice of license, a recipient has the option to distribute
 * your version of this file under either the CDDL, the GPL Version 2 or
 * to extend the choice of license to its licensees as provided above.
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 * Version 2 license, then the option applies only if the new code is
 * made subject to such option by the copyright holder.
 */

package org.netbeans.modules.mobility.cldcplatform.startup;
//package com.iplanet.ias.installer.utilities;

/** JDK Imports **/
import org.openide.ErrorManager;

import java.io.*;
import java.util.*;


/**  Solaris package and OS patch related utility functions
 * are defined here.
 **/


public class SolarisRoutines {
    
    /**  Find out if the package is available on the box,takes the package name as
     * argument. returns PkgInfo class.
     **/
    public static PkgInfo findPackage(final String packageName) {
        int result = -1;
        final StringBuffer cmdOutput = new StringBuffer();
        // Execute Solaris 'pkginfo' command and store the output in buffer for parsing
        try {
            result = executeRuntimeCommand( "/bin/pkginfo -i -l " + packageName,cmdOutput); // NOI18N
        } catch (Exception e) {
            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
            return null;
        }
        
        if ( result == 0) {
            // Pkginfo did not fail, so return it.
            return new SolarisRoutines.PkgInfo(cmdOutput);
        }
        return null;
    }
    
    
    /** Creates a script running showrev (workaround: otherwise Runtime.exec chokes on long outputs)
     * returns the file*/
    public static File createPatchScript()
    throws IOException{
        final File showrev = new File("/bin/showrev"); // NOI18N
        if (!showrev.exists()) {
            throw new FileNotFoundException("/bin/showrev is not found to check the installed patches"); // NOI18N
        }
        
        final File script = File.createTempFile("appserver-showrev", ".sh", new File("/tmp")); // NOI18N
        final Process proc = Runtime.getRuntime().exec("chmod +x " + script); // NOI18N
        try {
            proc.waitFor();
        } catch (Exception ex) {
            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
        }
        final FileWriter out = new FileWriter(script);
        out.write("/bin/showrev -p | grep $1\n"); // NOI18N
        out.close();
        return script;
    }
    
    /** checks whether all the patches in patchList are installed
     *  returns an array of uninstalled patches or null if all the patches are installed
     */
    public static String[] getUninstalledPatches(final String[] patchList)
    throws IOException{
        
        final File script = createPatchScript();
        final String filename = script.getAbsolutePath();
        final ArrayList<String> uninstalledPatches = new ArrayList<String>(Arrays.asList(patchList));
        final Iterator<String> iter = uninstalledPatches.iterator();
        while (iter.hasNext()) {
            final String patch = iter.next();
            if (checkPatch(patch, filename) == PATCH_INSTALLED) {
                iter.remove();
            }
        }
        script.delete();
        return (uninstalledPatches.size() > 0) ? (String[]) uninstalledPatches.toArray(new String[uninstalledPatches.size()]) : null;
    }
    
    /**  Check if the given patch is instaled on the box or not. Takes patch number as argument, returns
     * an integer indicating whether the patch is installed/missing or unknown.
     * scriptAbsolutePath: location of the script running showrev
     * (workaround: otherwise Runtime.exec chokes on long outputs)
     **/
    public static final int PATCH_INSTALLED = 0;
    public static final int PATCH_MISSING = 1; //needs new update for the patch
    public static final int PATCH_UNKNOWN = 2; //no info about patch
    
    public static int checkPatch(final String patchId, final String scriptAbsolutePath)
    {
        int result = -1;
        final StringBuffer cmdOutput = new StringBuffer();
        final String patchMajorVersion = patchId.substring(0,patchId.indexOf('-'));
        // Execute Solaris 'pkginfo' command and store the output in buffer for parsing
        try {
            result = executeRuntimeCommand(scriptAbsolutePath+ " " + patchMajorVersion, cmdOutput); // NOI18N
        } catch (Exception e) {
            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
            return PATCH_UNKNOWN;
        }
        //System.out.println("In checkPatch-> " + patchId + " " + result);
        if ( result == 0) {
            // showrev did not fail, so now parse the output buffer.
            if (checkPatchInstalled(patchId,cmdOutput)) {
                return PATCH_INSTALLED;
            }
            return PATCH_MISSING;
        } 
        return PATCH_UNKNOWN;
    }
    
    /**  Parses the output buffer of showrev -p cmd and scans for the given patch id in the
     * buffer. Returns true/false based on the scan results.
     **/
    private static boolean checkPatchInstalled(final String patchId, final StringBuffer buffer) {
        // First store all the lines with patch numbers in the vector
        final String output = buffer.toString();
        String infoString;
        final String patchMajorVersion = patchId.substring(0,patchId.indexOf('-'));
        final String patchMinorVersion = patchId.substring(patchId.indexOf('-')+1);
        int lineNum=0;
        int patchCount=0;
        int currentLine=0;
        int startIndex=0;
        // First go through the output and count the number of lines with the string "Patch:"
        lineNum = output.indexOf("Patch:", 0); // NOI18N
        while (lineNum != -1) {
            lineNum++;
            patchCount++;
            lineNum = output.indexOf("Patch:", lineNum); // NOI18N
        }
        lineNum = 0;
        while ( currentLine < patchCount ) {
            lineNum = output.indexOf("Patch:", lineNum+1); // NOI18N
            
            if ( lineNum == -1) {
                // We have reached the last occurence of patch string in the buffer..
                infoString =output.substring(startIndex);
            } else {
                infoString = output.substring(startIndex, lineNum);
            }
            /** Isolate the patch number alone from the output, In the string it will be like this
             * "Patch:  108940-07 <sometext>".
             **/
            final int beforePatchNum = infoString.indexOf(' ');
            final int afterPatchNum = infoString.indexOf(' ', beforePatchNum+1);
            final String patch = infoString.substring(beforePatchNum,afterPatchNum).trim();
            final String majorVersion = patch.substring(0,patch.indexOf('-'));
            final String minorVersion = patch.substring(patch.indexOf('-') + 1);
            
            if (majorVersion.equals(patchMajorVersion)) {
                if (minorVersion.compareTo(patchMinorVersion) >= 0) {
                    return true;
                }
            }
            
            startIndex = lineNum;
            currentLine++;
        }
        
        return false;
    }
    
    /** finds the pid of the process and then kills it with all its shildren processes */
  public static void killProcess(final String processCmd)
    {
        //strip the args
        String command = processCmd.trim();
        int index;
        if ((index = command.indexOf(' ')) != -1) // NOI18N
            command = command.substring(0, index);
        
        final String pgrepCmd = "/bin/pgrep -f " + command; // NOI18N
        final String ptreeCmd = "/bin/ptree "; // NOI18N
        final String killCmd = "/bin/kill -9 "; // NOI18N
        
        try {
            int result = -1;
            StringBuffer cmdOutput = new StringBuffer();
            result = executeRuntimeCommand( pgrepCmd, cmdOutput);
            //System.out.println("Pgrep -> \n" + cmdOutput.toString());
            if (( result == 0) && (cmdOutput.length() != 0)) {
                final StringTokenizer stArr = new StringTokenizer(cmdOutput.toString());
                while (stArr.hasMoreTokens()) {
                    cmdOutput = new StringBuffer();
                    final String token = stArr.nextToken().trim();
                    try {
                        Integer.valueOf(token);
                    } catch (NumberFormatException ex) {
                        //token is not an integer
                        continue;
                    }
                    //give some time so that most of the children are spawned
                    Thread.sleep(3000);
                    result = executeRuntimeCommand( ptreeCmd + token, cmdOutput);
                    if (( result == 0) && (cmdOutput.length() != 0)) {
                        final String pidList = parsePtreeInformation(cmdOutput, command);
                        result = executeRuntimeCommand( killCmd + pidList, cmdOutput);
                    }
                }
            }
        } catch (Exception e) {
            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
        }
    }
    
    /**Parse the ptree cmd output and get the pid's of the children processes
     **/
    private static String parsePtreeInformation(final StringBuffer buffer, final String command) {
        final StringTokenizer stArr = new StringTokenizer(buffer.toString(), "\n"); // NOI18N
        boolean isCmdFound = false;
        String pidList = ""; // NOI18N
        while (stArr.hasMoreTokens()) {
            final String token = stArr.nextToken().trim();
            int index;
            
            if (!isCmdFound) {
                if ((index = token.indexOf(command)) != -1) {
                    isCmdFound = true;
                } else
                    continue;
            }
            
            if ((index = token.indexOf(' ')) != -1) // NOI18N
                pidList = pidList + " " + token.substring(0,index); // NOI18N
        }
        return pidList;
    }
    
    public static int executeRuntimeCommand(final String command, final StringBuffer commandOutput)
    throws Exception{
        final Process proc = Runtime.getRuntime().exec(command);
        try {
            proc.waitFor();
        } catch (Exception ex) {
            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
        }
        final InputStream pIn = proc.getInputStream();
        final BufferedReader inputReader = new BufferedReader(new InputStreamReader(pIn));
        if (inputReader.ready()) {
            int eof = 0;
            while (eof != -1) {
                final char[] buffer = new char[250];
                eof = inputReader.read(buffer,0,250);
                commandOutput.append(buffer);
            }
        }
        inputReader.close();
        return proc.exitValue();
    }
    
    static class PkgInfo {
        private String version = ""; //NOI18N
        private String location = ""; //NOI18N
        private double versionNumber = 0;
        private Date revision;
        private String pkgInst = ""; //NOI18N
        
        private PkgInfo() {
            // to avoid instantiation
        }
        
        public PkgInfo(StringBuffer info) {
            parsePackageInformation(info);
        }
        
        //getters
        public String getPkgInst() { return pkgInst; }
        public String getVersion() { return version; }
        public String getLocation() { return location; }
        public double getVersionNumber() { return versionNumber;}
        public Date getRevision() { return revision; }
        
        /** Compares two PkgInfo versions.
         * Returns 0 if they are equal
         *         -1 if this PkgInfo is older
         *         1 if this pkgInfo is newer
         */
        public int compareTo(final PkgInfo pkg) {
            if (versionNumber > pkg.getVersionNumber()) return 1;
            else if (versionNumber < pkg.getVersionNumber()) return -1;
            //else check revision
            if (( revision != null) && (pkg.getRevision() != null)){
                return revision.compareTo(pkg.getRevision());
            }
            return 0;
        }
        
        /** Parse the pkginfo cmd output
         *  BASEDIR:. This will be location where the package is installed.
         *  VERSION:. This will be version of the package {VERSIONNUMBER + REVISON}
         **/
        private void parsePackageInformation(final StringBuffer buffer) {
            final StringTokenizer stArr = new StringTokenizer(buffer.toString());
            while (stArr.hasMoreTokens()) {
                final String token = stArr.nextToken();
                if ("BASEDIR:".equals(token)) { // NOI18N
                    location = stArr.nextToken();
                } else if ("PKGINST:".equals(token)) { // NOI18N
                    pkgInst = stArr.nextToken();
                } else if ("VERSION:".equals(token)) { // NOI18N
                    version = stArr.nextToken();
                    //TO DO: only supported in JDK1.4 -> split();
                    //for now, use the two lines below:
                    final String key = ",REV="; // NOI18N
                    final int index = version.indexOf(key);
                    if (index != -1) {
                        try {
                            versionNumber = Double.parseDouble(version.substring(0, index));
                            final String rev = version.substring(index + key.length());
                            final java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy.MM.dd.hh.mm"); // NOI18N
                            revision = formatter.parse(rev);
                        } catch (Exception ex) {
                            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
                            
                        }
                    }
                }
            }
        }
    }
    
    /**testing purposes*/
    public static void main(final String[] args) {
        try {
            final File script = createPatchScript();
            final String filename = script.getAbsolutePath();
            System.out.println("Checking patch 108827-35 -> " + checkPatch("108827-35", filename)); // NOI18N
            System.out.println("Checking patch 109326-09 -> " + checkPatch("109326-09", filename)); // NOI18N
            System.out.println("Checking patch 110380-04 -> " + checkPatch("110380-04", filename)); // NOI18N
            System.out.println("Checking patch 110934-10 -> " + checkPatch("110934-10", filename)); // NOI18N
            System.out.println("Checking patch 109320-01 -> " + checkPatch("109320-01", filename)); // NOI18N
            System.out.println("Checking patch 108435-05 -> " + checkPatch("108435-05", filename)); // NOI18N
            System.out.println("Class -> " + SolarisRoutines.class.getName()); // NOI18N
            System.out.println("os -> " + System.getProperty("os.arch") + " " // NOI18N
                    + System.getProperty("os.name") + " " // NOI18N
                    + System.getProperty("os.version")); // NOI18N
            script.delete();
            final String[] patches = new String[] {"108827-35", "109326-09", "110380-04", "110934-10", "109320-01", "108435-05"}; // NOI18N
            final String[] results = getUninstalledPatches(patches);
            final String resultStr = (results == null) ? "all installed" : Arrays.asList(results).toString(); // NOI18N
            System.out.println("All installed -> " + Arrays.asList(patches) + "\n" + resultStr); // NOI18N
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        
    }
    
}


java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.