/*
 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.print;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Vector;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import javax.print.DocFlavor;
import javax.print.MultiDocPrintService;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.HashPrintServiceAttributeSet;
import javax.print.attribute.PrintRequestAttribute;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.PrinterName;
import javax.print.attribute.standard.PrinterURI;
import java.io.File;
import java.io.FileReader;
import java.net.URL;
import java.nio.file.Files;

/*
 * Remind: This class uses solaris commands. We also need a linux
 * version
 */
public class UnixPrintServiceLookup extends PrintServiceLookup
    implements BackgroundServiceLookup, Runnable {

    /* Remind: the current implementation is static, as its assumed
     * its preferable to minimize creation of PrintService instances.
     * Later we should add logic to add/remove services on the fly which
     * will take a hit of needing to regather the list of services.
     */
    private String defaultPrinter;
    private PrintService defaultPrintService;
    private PrintService[] printServices; /* includes the default printer */
    private Vector lookupListeners = null;
    private static String debugPrefix = "UnixPrintServiceLookup>> ";
    private static boolean pollServices = true;
    private static final int DEFAULT_MINREFRESH = 120;  // 2 minutes
    private static int minRefreshTime = DEFAULT_MINREFRESH;


    static String osname;

    // List of commands used to deal with the printer queues on AIX
    String[] lpNameComAix = {
      "/usr/bin/lsallq",
      "/usr/bin/lpstat -W -p|/usr/bin/expand|/usr/bin/cut -f1 -d' '",
      "/usr/bin/lpstat -W -d|/usr/bin/expand|/usr/bin/cut -f1 -d' '",
      "/usr/bin/lpstat -W -v"
    };
    private static final int aix_lsallq = 0;
    private static final int aix_lpstat_p = 1;
    private static final int aix_lpstat_d = 2;
    private static final int aix_lpstat_v = 3;
    private static int aix_defaultPrinterEnumeration = aix_lsallq;

    static {
        /* The system property "sun.java2d.print.polling"
         * can be used to force the printing code to poll or not poll
         * for PrintServices.
         */
        String pollStr = java.security.AccessController.doPrivileged(
            new sun.security.action.GetPropertyAction("sun.java2d.print.polling"));

        if (pollStr != null) {
            if (pollStr.equalsIgnoreCase("true")) {
                pollServices = true;
            } else if (pollStr.equalsIgnoreCase("false")) {
                pollServices = false;
            }
        }

        /* The system property "sun.java2d.print.minRefreshTime"
         * can be used to specify minimum refresh time (in seconds)
         * for polling PrintServices.  The default is 120.
         */
        String refreshTimeStr = java.security.AccessController.doPrivileged(
            new sun.security.action.GetPropertyAction(
                "sun.java2d.print.minRefreshTime"));

        if (refreshTimeStr != null) {
            try {
                minRefreshTime = (new Integer(refreshTimeStr)).intValue();
            } catch (NumberFormatException e) {
            }
            if (minRefreshTime < DEFAULT_MINREFRESH) {
                minRefreshTime = DEFAULT_MINREFRESH;
            }
        }

        osname = java.security.AccessController.doPrivileged(
            new sun.security.action.GetPropertyAction("os.name"));

        /* The system property "sun.java2d.print.aix.lpstat"
         * can be used to force the usage of 'lpstat -p' to enumerate all
         * printer queues. By default we use 'lsallq', because 'lpstat -p' can
         * take lots of time if thousands of printers are attached to a server.
         */
        if (isAIX()) {
            String aixPrinterEnumerator = java.security.AccessController.doPrivileged(
                new sun.security.action.GetPropertyAction("sun.java2d.print.aix.lpstat"));

            if (aixPrinterEnumerator != null) {
                if (aixPrinterEnumerator.equalsIgnoreCase("lpstat")) {
                    aix_defaultPrinterEnumeration = aix_lpstat_p;
                } else if (aixPrinterEnumerator.equalsIgnoreCase("lsallq")) {
                    aix_defaultPrinterEnumeration = aix_lsallq;
                }
            }
        }
    }

    static boolean isMac() {
        return osname.startsWith("Mac");
    }

    static boolean isSysV() {
        return osname.equals("SunOS");
    }

    static boolean isLinux() {
        return (osname.equals("Linux"));
    }

    static boolean isBSD() {
        return (osname.equals("Linux") ||
                osname.contains("OS X"));
    }

    static boolean isAIX() {
        return osname.equals("AIX");
    }

    static final int UNINITIALIZED = -1;
    static final int BSD_LPD = 0;
    static final int BSD_LPD_NG = 1;

    static int cmdIndex = UNINITIALIZED;

    String[] lpcFirstCom = {
        "/usr/sbin/lpc status | grep : | sed -ne '1,1 s/://p'",
        "/usr/sbin/lpc status | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'"
    };

    String[] lpcAllCom = {
        "/usr/sbin/lpc status all | grep : | sed -e 's/://'",
        "/usr/sbin/lpc status all | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}' | sort"
    };

    String[] lpcNameCom = {
        "| grep : | sed -ne 's/://p'",
        "| grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'"
    };


    static int getBSDCommandIndex() {
        String command  = "/usr/sbin/lpc status all";
        String[] names = execCmd(command);

        if ((names == null) || (names.length == 0)) {
            return BSD_LPD_NG;
        }

        for (int i=0; i<names.length; i++) {
            if (names[i].indexOf('@') != -1) {
                return BSD_LPD_NG;
            }
        }

        return BSD_LPD;
    }


    public UnixPrintServiceLookup() {
        // start the printer listener thread
        if (pollServices) {
            PrinterChangeListener thr = new PrinterChangeListener();
            thr.setDaemon(true);
            thr.start();
            IPPPrintService.debug_println(debugPrefix+"polling turned on");
        }
    }

    /* Want the PrintService which is default print service to have
     * equality of reference with the equivalent in list of print services
     * This isn't required by the API and there's a risk doing this will
     * lead people to assume its guaranteed.
     */
    public synchronized PrintService[] getPrintServices() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPrintJobAccess();
        }

        if (printServices == null || !pollServices) {
            refreshServices();
        }
        if (printServices == null) {
            return new PrintService[0];
        } else {
            return (PrintService[])printServices.clone();
        }
    }

    private int addPrintServiceToList(ArrayList printerList, PrintService ps) {
        int index = printerList.indexOf(ps);
        // Check if PrintService with same name is already in the list.
        if (CUPSPrinter.isCupsRunning() && index != -1) {
            // Bug in Linux: Duplicate entry of a remote printer
            // and treats it as local printer but it is returning wrong
            // information when queried using IPP. Workaround is to remove it.
            // Even CUPS ignores these entries as shown in lpstat or using
            // their web configuration.
            PrinterURI uri = (PrinterURI)ps.getAttribute(PrinterURI.class);
            if (uri.getURI().getHost().equals("localhost")) {
                IPPPrintService.debug_println(debugPrefix+"duplicate PrintService, ignoring the new local printer: "+ps);
                return index;  // Do not add this.
            }
            PrintService oldPS = (PrintService)(printerList.get(index));
            uri = (PrinterURI)oldPS.getAttribute(PrinterURI.class);
            if (uri.getURI().getHost().equals("localhost")) {
                IPPPrintService.debug_println(debugPrefix+"duplicate PrintService, removing existing local printer: "+oldPS);
                printerList.remove(oldPS);
            } else {
                return index;
            }
        }
        printerList.add(ps);
        return (printerList.size() - 1);
    }


    // refreshes "printServices"
    public synchronized void refreshServices() {
        /* excludes the default printer */
        String[] printers = null; // array of printer names
        String[] printerURIs = null; //array of printer URIs

        try {
            getDefaultPrintService();
        } catch (Throwable t) {
            IPPPrintService.debug_println(debugPrefix+
              "Exception getting default printer : " + t);
        }
        if (CUPSPrinter.isCupsRunning()) {
            try {
                printerURIs = CUPSPrinter.getAllPrinters();
                IPPPrintService.debug_println("CUPS URIs = " + printerURIs);
                if (printerURIs != null) {
                    for (int p = 0; p < printerURIs.length; p++) {
                       IPPPrintService.debug_println("URI="+printerURIs[p]);
                    }
                }
            } catch (Throwable t) {
            IPPPrintService.debug_println(debugPrefix+
              "Exception getting all CUPS printers : " + t);
            }
            if ((printerURIs != null) && (printerURIs.length > 0)) {
                printers = new String[printerURIs.length];
                for (int i=0; i<printerURIs.length; i++) {
                    int lastIndex = printerURIs[i].lastIndexOf("/");
                    printers[i] = printerURIs[i].substring(lastIndex+1);
                }
            }
        } else {
            if (isMac() || isSysV()) {
                printers = getAllPrinterNamesSysV();
            } else if (isAIX()) {
                printers = getAllPrinterNamesAIX();
            } else { //BSD
                printers = getAllPrinterNamesBSD();
            }
        }

        if (printers == null) {
            if (defaultPrintService != null) {
                printServices = new PrintService[1];
                printServices[0] = defaultPrintService;
            } else {
                printServices = null;
            }
            return;
        }

        ArrayList printerList = new ArrayList();
        int defaultIndex = -1;
        for (int p=0; p<printers.length; p++) {
            if (printers[p] == null) {
                continue;
            }
            if ((defaultPrintService != null)
                && printers[p].equals(getPrinterDestName(defaultPrintService))) {
                defaultIndex = addPrintServiceToList(printerList, defaultPrintService);
            } else {
                if (printServices == null) {
                    IPPPrintService.debug_println(debugPrefix+
                                                  "total# of printers = "+printers.length);

                    if (CUPSPrinter.isCupsRunning()) {
                        try {
                            addPrintServiceToList(printerList,
                                                  new IPPPrintService(printers[p],
                                                                   printerURIs[p],
                                                                   true));
                        } catch (Exception e) {
                            IPPPrintService.debug_println(debugPrefix+
                                                          " getAllPrinters Exception "+
                                                          e);

                        }
                    } else {
                        printerList.add(new UnixPrintService(printers[p]));
                    }
                } else {
                    int j;
                    for (j=0; j<printServices.length; j++) {
                        if (printServices[j] != null) {
                            if (printers[p].equals(getPrinterDestName(printServices[j]))) {
                                printerList.add(printServices[j]);
                                printServices[j] = null;
                                break;
                            }
                        }
                    }

                    if (j == printServices.length) {      // not found?
                        if (CUPSPrinter.isCupsRunning()) {
                            try {
                                addPrintServiceToList(printerList,
                                             new IPPPrintService(printers[p],
                                                                 printerURIs[p],
                                                                 true));
                            } catch (Exception e) {
                                IPPPrintService.debug_println(debugPrefix+
                                                              " getAllPrinters Exception "+
                                                              e);

                            }
                        } else {
                            printerList.add(new UnixPrintService(printers[p]));
                        }
                    }
                }
            }
        }

        // Look for deleted services and invalidate these
        if (printServices != null) {
            for (int j=0; j < printServices.length; j++) {
                if ((printServices[j] instanceof UnixPrintService) &&
                    (!printServices[j].equals(defaultPrintService))) {
                    ((UnixPrintService)printServices[j]).invalidateService();
                }
            }
        }

        //if defaultService is not found in printerList
        if (defaultIndex == -1 && defaultPrintService != null) {
            defaultIndex = addPrintServiceToList(printerList, defaultPrintService);
        }

        printServices = (PrintService[])printerList.toArray(
                                      new PrintService[] {});

        // swap default with the first in the list
        if (defaultIndex > 0) {
            PrintService saveService = printServices[0];
            printServices[0] = printServices[defaultIndex];
            printServices[defaultIndex] = saveService;
        }
    }

    private boolean matchesAttributes(PrintService service,
                                      PrintServiceAttributeSet attributes) {

        Attribute [] attrs =  attributes.toArray();
        Attribute serviceAttr;
        for (int i=0; i<attrs.length; i++) {
            serviceAttr
                = service.getAttribute((Class<PrintServiceAttribute>)attrs[i].getCategory());
            if (serviceAttr == null || !serviceAttr.equals(attrs[i])) {
                return false;
            }
        }
        return true;
    }

      /* This checks for validity of the printer name before passing as
       * parameter to a shell command.
       */
      private boolean checkPrinterName(String s) {
        char c;

        for (int i=0; i < s.length(); i++) {
          c = s.charAt(i);
          if (Character.isLetterOrDigit(c) ||
              c == '-' || c == '_' || c == '.' || c == '/') {
            continue;
          } else {
            return false;
          }
        }
        return true;
      }

    /*
     * Gets the printer name compatible with the list of printers returned by
     * the system when we query default or all the available printers.
     */
    private String getPrinterDestName(PrintService ps) {
        if (isMac()) {
            return ((IPPPrintService)ps).getDest();
        }
        return ps.getName();
    }

    /* On a network with many (hundreds) of network printers, it
     * can save several seconds if you know all you want is a particular
     * printer, to ask for that printer rather than retrieving all printers.
     */
    private PrintService getServiceByName(PrinterName nameAttr) {
        String name = nameAttr.getValue();
        if (name == null || name.equals("") || !checkPrinterName(name)) {
            return null;
        }
        /* check if all printers are already available */
        if (printServices != null) {
            for (PrintService printService : printServices) {
                PrinterName printerName =
                    (PrinterName)printService.getAttribute(PrinterName.class);
                if (printerName.getValue().equals(name)) {
                    return printService;
                }
            }
        }
        /* take CUPS into account first */
        if (CUPSPrinter.isCupsRunning()) {
            try {
                return new IPPPrintService(name,
                                           new URL("http://"+
                                                   CUPSPrinter.getServer()+":"+
                                                   CUPSPrinter.getPort()+"/"+
                                                   name));
            } catch (Exception e) {
                IPPPrintService.debug_println(debugPrefix+
                                              " getServiceByName Exception "+
                                              e);
            }
        }
        /* fallback if nothing not having a printer at this point */
        PrintService printer = null;
        if (isMac() || isSysV()) {
            printer = getNamedPrinterNameSysV(name);
        } else if (isAIX()) {
            printer = getNamedPrinterNameAIX(name);
        } else {
            printer = getNamedPrinterNameBSD(name);
        }
        return printer;
    }

    private PrintService[]
        getPrintServices(PrintServiceAttributeSet serviceSet) {

        if (serviceSet == null || serviceSet.isEmpty()) {
            return getPrintServices();
        }

        /* Typically expect that if a service attribute is specified that
         * its a printer name and there ought to be only one match.
         * Directly retrieve that service and confirm
         * that it meets the other requirements.
         * If printer name isn't mentioned then go a slow path checking
         * all printers if they meet the reqiremements.
         */
        PrintService[] services;
        PrinterName name = (PrinterName)serviceSet.get(PrinterName.class);
        PrintService defService;
        if (name != null && (defService = getDefaultPrintService()) != null) {
            /* To avoid execing a unix command  see if the client is asking
             * for the default printer by name, since we already have that
             * initialised.
             */

            PrinterName defName =
                (PrinterName)defService.getAttribute(PrinterName.class);

            if (defName != null && name.equals(defName)) {
                if (matchesAttributes(defService, serviceSet)) {
                    services = new PrintService[1];
                    services[0] = defService;
                    return services;
                } else {
                    return new PrintService[0];
                }
            } else {
                /* Its not the default service */
                PrintService service = getServiceByName(name);
                if (service != null &&
                    matchesAttributes(service, serviceSet)) {
                    services = new PrintService[1];
                    services[0] = service;
                    return services;
                } else {
                    return new PrintService[0];
                }
            }
        } else {
            /* specified service attributes don't include a name.*/
            Vector matchedServices = new Vector();
            services = getPrintServices();
            for (int i = 0; i< services.length; i++) {
                if (matchesAttributes(services[i], serviceSet)) {
                    matchedServices.add(services[i]);
                }
            }
            services = new PrintService[matchedServices.size()];
            for (int i = 0; i< services.length; i++) {
                services[i] = (PrintService)matchedServices.elementAt(i);
            }
            return services;
        }
    }

    /*
     * If service attributes are specified then there must be additional
     * filtering.
     */
    public PrintService[] getPrintServices(DocFlavor flavor,
                                           AttributeSet attributes) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
          security.checkPrintJobAccess();
        }
        PrintRequestAttributeSet requestSet = null;
        PrintServiceAttributeSet serviceSet = null;

        if (attributes != null && !attributes.isEmpty()) {

            requestSet = new HashPrintRequestAttributeSet();
            serviceSet = new HashPrintServiceAttributeSet();

            Attribute[] attrs = attributes.toArray();
            for (int i=0; i<attrs.length; i++) {
                if (attrs[i] instanceof PrintRequestAttribute) {
                    requestSet.add(attrs[i]);
                } else if (attrs[i] instanceof PrintServiceAttribute) {
                    serviceSet.add(attrs[i]);
                }
            }
        }

        PrintService[] services = getPrintServices(serviceSet);
        if (services.length == 0) {
            return services;
        }

        if (CUPSPrinter.isCupsRunning()) {
            ArrayList matchingServices = new ArrayList();
            for (int i=0; i<services.length; i++) {
                try {
                    if (services[i].
                        getUnsupportedAttributes(flavor, requestSet) == null) {
                        matchingServices.add(services[i]);
                    }
                } catch (IllegalArgumentException e) {
                }
            }
            services = new PrintService[matchingServices.size()];
            return (PrintService[])matchingServices.toArray(services);

        } else {
            // We only need to compare 1 PrintService because all
            // UnixPrintServices are the same anyway.  We will not use
            // default PrintService because it might be null.
            PrintService service = services[0];
            if ((flavor == null ||
                 service.isDocFlavorSupported(flavor)) &&
                 service.getUnsupportedAttributes(flavor, requestSet) == null)
            {
                return services;
            } else {
                return new PrintService[0];
            }
        }
    }

    /*
     * return empty array as don't support multi docs
     */
    public MultiDocPrintService[]
        getMultiDocPrintServices(DocFlavor[] flavors,
                                 AttributeSet attributes) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
          security.checkPrintJobAccess();
        }
        return new MultiDocPrintService[0];
    }


    public synchronized PrintService getDefaultPrintService() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
          security.checkPrintJobAccess();
        }

        // clear defaultPrintService
        defaultPrintService = null;
        String psuri = null;

        IPPPrintService.debug_println("isRunning ? "+
                                      (CUPSPrinter.isCupsRunning()));
        if (CUPSPrinter.isCupsRunning()) {
            String[] printerInfo = CUPSPrinter.getDefaultPrinter();
            if (printerInfo != null && printerInfo.length >= 2) {
                defaultPrinter = printerInfo[0];
                psuri = printerInfo[1];
            }
        } else {
            if (isMac() || isSysV()) {
                defaultPrinter = getDefaultPrinterNameSysV();
            } else if (isAIX()) {
                defaultPrinter = getDefaultPrinterNameAIX();
            } else {
                defaultPrinter = getDefaultPrinterNameBSD();
            }
        }
        if (defaultPrinter == null) {
            return null;
        }
        defaultPrintService = null;
        if (printServices != null) {
            for (int j=0; j<printServices.length; j++) {
                if (defaultPrinter.equals(getPrinterDestName(printServices[j]))) {
                    defaultPrintService = printServices[j];
                    break;
                }
            }
        }
        if (defaultPrintService == null) {
            if (CUPSPrinter.isCupsRunning()) {
                try {
                    PrintService defaultPS;
                    if ((psuri != null) && !psuri.startsWith("file")) {
                        defaultPS = new IPPPrintService(defaultPrinter,
                                                        psuri, true);
                    } else {
                        defaultPS = new IPPPrintService(defaultPrinter,
                                            new URL("http://"+
                                                    CUPSPrinter.getServer()+":"+
                                                    CUPSPrinter.getPort()+"/"+
                                                    defaultPrinter));
                    }
                    defaultPrintService = defaultPS;
                } catch (Exception e) {
                }
            } else {
                defaultPrintService = new UnixPrintService(defaultPrinter);
            }
        }

        return defaultPrintService;
    }

    public synchronized void
        getServicesInbackground(BackgroundLookupListener listener) {
        if (printServices != null) {
            listener.notifyServices(printServices);
        } else {
            if (lookupListeners == null) {
                lookupListeners = new Vector();
                lookupListeners.add(listener);
                Thread lookupThread = new Thread(this);
                lookupThread.start();
            } else {
                lookupListeners.add(listener);
            }
        }
    }

    /* This method isn't used in most cases because we rely on code in
     * javax.print.PrintServiceLookup. This is needed just for the cases
     * where those interfaces are by-passed.
     */
    private PrintService[] copyOf(PrintService[] inArr) {
        if (inArr == null || inArr.length == 0) {
            return inArr;
        } else {
            PrintService []outArr = new PrintService[inArr.length];
            System.arraycopy(inArr, 0, outArr, 0, inArr.length);
            return outArr;
        }
    }

    public void run() {
        PrintService[] services = getPrintServices();
        synchronized (this) {
            BackgroundLookupListener listener;
            for (int i=0; i<lookupListeners.size(); i++) {
                listener =
                    (BackgroundLookupListener)lookupListeners.elementAt(i);
                listener.notifyServices(copyOf(services));
            }
            lookupListeners = null;
        }
    }

    private String getDefaultPrinterNameBSD() {
        if (cmdIndex == UNINITIALIZED) {
            cmdIndex = getBSDCommandIndex();
        }
        String[] names = execCmd(lpcFirstCom[cmdIndex]);
        if (names == null || names.length == 0) {
            return null;
        }

        if ((cmdIndex==BSD_LPD_NG) &&
            (names[0].startsWith("missingprinter"))) {
            return null;
        }
        return names[0];
    }

    private PrintService getNamedPrinterNameBSD(String name) {
      if (cmdIndex == UNINITIALIZED) {
        cmdIndex = getBSDCommandIndex();
      }
      String command = "/usr/sbin/lpc status " + name + lpcNameCom[cmdIndex];
      String[] result = execCmd(command);

      if (result == null || !(result[0].equals(name))) {
          return null;
      }
      return new UnixPrintService(name);
    }

    private String[] getAllPrinterNamesBSD() {
        if (cmdIndex == UNINITIALIZED) {
            cmdIndex = getBSDCommandIndex();
        }
        String[] names = execCmd(lpcAllCom[cmdIndex]);
        if (names == null || names.length == 0) {
          return null;
        }
        return names;
    }

    static String getDefaultPrinterNameSysV() {
        String defaultPrinter = "lp";
        String command = "/usr/bin/lpstat -d";

        String [] names = execCmd(command);
        if (names == null || names.length == 0) {
            return defaultPrinter;
        } else {
            int index = names[0].indexOf(":");
            if (index == -1  || (names[0].length() <= index+1)) {
                return null;
            } else {
                String name = names[0].substring(index+1).trim();
                if (name.length() == 0) {
                    return null;
                } else {
                    return name;
                }
            }
        }
    }

    private PrintService getNamedPrinterNameSysV(String name) {

        String command = "/usr/bin/lpstat -v " + name;
        String []result = execCmd(command);

        if (result == null || result[0].indexOf("unknown printer") > 0) {
            return null;
        } else {
            return new UnixPrintService(name);
        }
    }

    private String[] getAllPrinterNamesSysV() {
        String defaultPrinter = "lp";
        String command = "/usr/bin/lpstat -v|/usr/bin/expand|/usr/bin/cut -f3 -d' ' |/usr/bin/cut -f1 -d':' | /usr/bin/sort";

        String [] names = execCmd(command);
        ArrayList printerNames = new ArrayList();
        for (int i=0; i < names.length; i++) {
            if (!names[i].equals("_default") &&
                !names[i].equals(defaultPrinter) &&
                !names[i].equals("")) {
                printerNames.add(names[i]);
            }
        }
        return (String[])printerNames.toArray(new String[printerNames.size()]);
    }

    private String getDefaultPrinterNameAIX() {
        String[] names = execCmd(lpNameComAix[aix_lpstat_d]);
        // Remove headers and bogus entries added by remote printers.
        names = UnixPrintService.filterPrinterNamesAIX(names);
        if (names == null || names.length != 1) {
            // No default printer found
            return null;
        } else {
            return names[0];
        }
    }

    private PrintService getNamedPrinterNameAIX(String name) {
        // On AIX there should be no blank after '-v'.
        String[] result = execCmd(lpNameComAix[aix_lpstat_v] + name);
        // Remove headers and bogus entries added by remote printers.
        result = UnixPrintService.filterPrinterNamesAIX(result);
        if (result == null || result.length != 1) {
            return null;
        } else {
            return new UnixPrintService(name);
        }
    }

    private String[] getAllPrinterNamesAIX() {
        // Determine all printers of the system.
        String [] names = execCmd(lpNameComAix[aix_defaultPrinterEnumeration]);

        // Remove headers and bogus entries added by remote printers.
        names = UnixPrintService.filterPrinterNamesAIX(names);

        ArrayList<String> printerNames = new ArrayList<String>();
        for ( int i=0; i < names.length; i++) {
            printerNames.add(names[i]);
        }
        return (String[])printerNames.toArray(new String[printerNames.size()]);
    }

    static String[] execCmd(final String command) {
        ArrayList results = null;
        try {
            final String[] cmd = new String[3];
            if (isSysV() || isAIX()) {
                cmd[0] = "/usr/bin/sh";
                cmd[1] = "-c";
                cmd[2] = "env LC_ALL=C " + command;
            } else {
                cmd[0] = "/bin/sh";
                cmd[1] = "-c";
                cmd[2] = "LC_ALL=C " + command;
            }

            results = (ArrayList)AccessController.doPrivileged(
                new PrivilegedExceptionAction() {
                    public Object run() throws IOException {

                        Process proc;
                        BufferedReader bufferedReader = null;
                        File f = Files.createTempFile("prn","xc").toFile();
                        cmd[2] = cmd[2]+">"+f.getAbsolutePath();

                        proc = Runtime.getRuntime().exec(cmd);
                        try {
                            boolean done = false; // in case of interrupt.
                            while (!done) {
                                try {
                                    proc.waitFor();
                                    done = true;
                                } catch (InterruptedException e) {
                                }
                            }

                            if (proc.exitValue() == 0) {
                                FileReader reader = new FileReader(f);
                                bufferedReader = new BufferedReader(reader);
                                String line;
                                ArrayList results = new ArrayList();
                                while ((line = bufferedReader.readLine())
                                       != null) {
                                    results.add(line);
                                }
                                return results;
                            }
                        } finally {
                            f.delete();
                            // promptly close all streams.
                            if (bufferedReader != null) {
                                bufferedReader.close();
                            }
                            proc.getInputStream().close();
                            proc.getErrorStream().close();
                            proc.getOutputStream().close();
                        }
                        return null;
                    }
                });
        } catch (PrivilegedActionException e) {
        }
        if (results == null) {
            return new String[0];
        } else {
            return (String[])results.toArray(new String[results.size()]);
        }
    }

    private class PrinterChangeListener extends Thread {

        public void run() {
            int refreshSecs;
            while (true) {
                try {
                    refreshServices();
                } catch (Exception se) {
                    IPPPrintService.debug_println(debugPrefix+"Exception in refresh thread.");
                    break;
                }

                if ((printServices != null) &&
                    (printServices.length > minRefreshTime)) {
                    // compute new refresh time 1 printer = 1 sec
                    refreshSecs = printServices.length;
                } else {
                    refreshSecs = minRefreshTime;
                }
                try {
                    sleep(refreshSecs * 1000);
                } catch (InterruptedException e) {
                    break;
                }
            }
        }
    }
}
