0N/A/*
4944N/A * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.print;
0N/A
0N/Aimport java.io.BufferedReader;
0N/Aimport java.io.FileInputStream;
0N/Aimport java.io.InputStream;
0N/Aimport java.io.InputStreamReader;
0N/Aimport java.io.IOException;
0N/Aimport java.util.ArrayList;
0N/Aimport java.util.Vector;
0N/Aimport java.security.AccessController;
0N/Aimport java.security.PrivilegedActionException;
0N/Aimport java.security.PrivilegedExceptionAction;
0N/Aimport javax.print.DocFlavor;
0N/Aimport javax.print.MultiDocPrintService;
0N/Aimport javax.print.PrintService;
0N/Aimport javax.print.PrintServiceLookup;
0N/Aimport javax.print.attribute.Attribute;
0N/Aimport javax.print.attribute.AttributeSet;
0N/Aimport javax.print.attribute.HashPrintRequestAttributeSet;
0N/Aimport javax.print.attribute.HashPrintServiceAttributeSet;
0N/Aimport javax.print.attribute.PrintRequestAttribute;
0N/Aimport javax.print.attribute.PrintRequestAttributeSet;
0N/Aimport javax.print.attribute.PrintServiceAttribute;
0N/Aimport javax.print.attribute.PrintServiceAttributeSet;
0N/Aimport javax.print.attribute.standard.PrinterName;
0N/Aimport java.io.File;
0N/Aimport java.io.FileReader;
0N/Aimport java.net.URL;
5089N/Aimport java.nio.file.Files;
0N/A
0N/A/*
0N/A * Remind: This class uses solaris commands. We also need a linux
0N/A * version
0N/A */
0N/Apublic class UnixPrintServiceLookup extends PrintServiceLookup
0N/A implements BackgroundServiceLookup, Runnable {
0N/A
0N/A /* Remind: the current implementation is static, as its assumed
0N/A * its preferable to minimise creation of PrintService instances.
0N/A * Later we should add logic to add/remove services on the fly which
0N/A * will take a hit of needing to regather the list of services.
0N/A */
0N/A private String defaultPrinter;
0N/A private PrintService defaultPrintService;
0N/A private PrintService[] printServices; /* includes the default printer */
0N/A private Vector lookupListeners = null;
0N/A private static String debugPrefix = "UnixPrintServiceLookup>> ";
0N/A private static boolean pollServices = true;
0N/A private static final int DEFAULT_MINREFRESH = 120; // 2 minutes
0N/A private static int minRefreshTime = DEFAULT_MINREFRESH;
0N/A
0N/A
0N/A static String osname;
0N/A
0N/A static {
0N/A /* The system property "sun.java2d.print.polling"
0N/A * can be used to force the printing code to poll or not poll
0N/A * for PrintServices.
0N/A */
0N/A String pollStr = java.security.AccessController.doPrivileged(
0N/A new sun.security.action.GetPropertyAction("sun.java2d.print.polling"));
0N/A
0N/A if (pollStr != null) {
0N/A if (pollStr.equalsIgnoreCase("true")) {
0N/A pollServices = true;
0N/A } else if (pollStr.equalsIgnoreCase("false")) {
0N/A pollServices = false;
0N/A }
0N/A }
0N/A
0N/A /* The system property "sun.java2d.print.minRefreshTime"
0N/A * can be used to specify minimum refresh time (in seconds)
0N/A * for polling PrintServices. The default is 120.
0N/A */
0N/A String refreshTimeStr = java.security.AccessController.doPrivileged(
0N/A new sun.security.action.GetPropertyAction(
0N/A "sun.java2d.print.minRefreshTime"));
0N/A
0N/A if (refreshTimeStr != null) {
0N/A try {
0N/A minRefreshTime = (new Integer(refreshTimeStr)).intValue();
0N/A } catch (NumberFormatException e) {
0N/A }
0N/A if (minRefreshTime < DEFAULT_MINREFRESH) {
0N/A minRefreshTime = DEFAULT_MINREFRESH;
0N/A }
0N/A }
0N/A
0N/A osname = java.security.AccessController.doPrivileged(
0N/A new sun.security.action.GetPropertyAction("os.name"));
0N/A }
0N/A
5145N/A static boolean isMac() {
5145N/A return osname.contains("OS X");
5145N/A }
5145N/A
0N/A static boolean isSysV() {
0N/A return osname.equals("SunOS");
0N/A }
0N/A
0N/A static boolean isBSD() {
4632N/A return (osname.equals("Linux") ||
4944N/A osname.contains("OS X"));
0N/A }
0N/A
0N/A static final int UNINITIALIZED = -1;
0N/A static final int BSD_LPD = 0;
0N/A static final int BSD_LPD_NG = 1;
0N/A
0N/A static int cmdIndex = UNINITIALIZED;
0N/A
0N/A String[] lpcFirstCom = {
0N/A "/usr/sbin/lpc status | grep : | sed -ne '1,1 s/://p'",
0N/A "/usr/sbin/lpc status | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'"
0N/A };
0N/A
0N/A String[] lpcAllCom = {
4632N/A "/usr/sbin/lpc status all | grep : | sed -e 's/://'",
4632N/A "/usr/sbin/lpc status all | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}' | sort"
0N/A };
0N/A
0N/A String[] lpcNameCom = {
0N/A "| grep : | sed -ne 's/://p'",
0N/A "| grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'"
0N/A };
0N/A
0N/A
0N/A static int getBSDCommandIndex() {
4632N/A String command = "/usr/sbin/lpc status all";
0N/A String[] names = execCmd(command);
0N/A
0N/A if ((names == null) || (names.length == 0)) {
0N/A return BSD_LPD_NG;
0N/A }
0N/A
0N/A for (int i=0; i<names.length; i++) {
0N/A if (names[i].indexOf('@') != -1) {
0N/A return BSD_LPD_NG;
0N/A }
0N/A }
0N/A
0N/A return BSD_LPD;
0N/A }
0N/A
0N/A
0N/A public UnixPrintServiceLookup() {
0N/A // start the printer listener thread
0N/A if (pollServices) {
0N/A PrinterChangeListener thr = new PrinterChangeListener();
0N/A thr.setDaemon(true);
0N/A thr.start();
0N/A IPPPrintService.debug_println(debugPrefix+"polling turned on");
0N/A }
0N/A }
0N/A
0N/A /* Want the PrintService which is default print service to have
0N/A * equality of reference with the equivalent in list of print services
0N/A * This isn't required by the API and there's a risk doing this will
0N/A * lead people to assume its guaranteed.
0N/A */
0N/A public synchronized PrintService[] getPrintServices() {
0N/A SecurityManager security = System.getSecurityManager();
0N/A if (security != null) {
0N/A security.checkPrintJobAccess();
0N/A }
0N/A
0N/A if (printServices == null || !pollServices) {
0N/A refreshServices();
0N/A }
0N/A if (printServices == null) {
0N/A return new PrintService[0];
0N/A } else {
0N/A return printServices;
0N/A }
0N/A }
0N/A
0N/A
0N/A // refreshes "printServices"
0N/A public synchronized void refreshServices() {
293N/A /* excludes the default printer */
293N/A String[] printers = null; // array of printer names
293N/A String[] printerURIs = null; //array of printer URIs
0N/A
0N/A getDefaultPrintService();
0N/A if (CUPSPrinter.isCupsRunning()) {
293N/A printerURIs = CUPSPrinter.getAllPrinters();
293N/A if ((printerURIs != null) && (printerURIs.length > 0)) {
293N/A printers = new String[printerURIs.length];
293N/A for (int i=0; i<printerURIs.length; i++) {
293N/A int lastIndex = printerURIs[i].lastIndexOf("/");
293N/A printers[i] = printerURIs[i].substring(lastIndex+1);
293N/A }
293N/A }
0N/A } else {
5145N/A if (isMac() || isSysV()) {
0N/A printers = getAllPrinterNamesSysV();
0N/A } else { //BSD
0N/A printers = getAllPrinterNamesBSD();
0N/A }
0N/A }
0N/A
0N/A if (printers == null) {
0N/A if (defaultPrintService != null) {
0N/A printServices = new PrintService[1];
0N/A printServices[0] = defaultPrintService;
0N/A } else {
0N/A printServices = null;
0N/A }
0N/A return;
0N/A }
0N/A
0N/A ArrayList printerList = new ArrayList();
0N/A int defaultIndex = -1;
0N/A for (int p=0; p<printers.length; p++) {
0N/A if (printers[p] == null) {
0N/A continue;
0N/A }
0N/A if ((defaultPrintService != null)
0N/A && printers[p].equals(defaultPrintService.getName())) {
0N/A printerList.add(defaultPrintService);
0N/A defaultIndex = printerList.size() - 1;
0N/A } else {
0N/A if (printServices == null) {
0N/A IPPPrintService.debug_println(debugPrefix+
0N/A "total# of printers = "+printers.length);
0N/A
0N/A if (CUPSPrinter.isCupsRunning()) {
0N/A try {
293N/A printerList.add(new IPPPrintService(printers[p],
293N/A printerURIs[p],
293N/A true));
0N/A } catch (Exception e) {
0N/A IPPPrintService.debug_println(debugPrefix+
0N/A " getAllPrinters Exception "+
0N/A e);
0N/A
0N/A }
0N/A } else {
0N/A printerList.add(new UnixPrintService(printers[p]));
0N/A }
0N/A } else {
0N/A int j;
0N/A for (j=0; j<printServices.length; j++) {
0N/A if ((printServices[j] != null) &&
0N/A (printers[p].equals(printServices[j].getName()))) {
0N/A printerList.add(printServices[j]);
0N/A printServices[j] = null;
0N/A break;
0N/A }
0N/A }
0N/A
0N/A if (j == printServices.length) { // not found?
0N/A if (CUPSPrinter.isCupsRunning()) {
0N/A try {
293N/A printerList.add(new IPPPrintService(
293N/A printers[p],
293N/A printerURIs[p],
293N/A true));
0N/A } catch (Exception e) {
0N/A IPPPrintService.debug_println(debugPrefix+
0N/A " getAllPrinters Exception "+
0N/A e);
0N/A
0N/A }
0N/A } else {
0N/A printerList.add(new UnixPrintService(printers[p]));
0N/A }
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A // Look for deleted services and invalidate these
0N/A if (printServices != null) {
0N/A for (int j=0; j < printServices.length; j++) {
0N/A if ((printServices[j] instanceof UnixPrintService) &&
0N/A (!printServices[j].equals(defaultPrintService))) {
0N/A ((UnixPrintService)printServices[j]).invalidateService();
0N/A }
0N/A }
0N/A }
0N/A
0N/A //if defaultService is not found in printerList
0N/A if (defaultIndex == -1 && defaultPrintService != null) {
0N/A //add default to the list
0N/A printerList.add(defaultPrintService);
0N/A defaultIndex = printerList.size() - 1;
0N/A }
0N/A
0N/A printServices = (PrintService[])printerList.toArray(
0N/A new PrintService[] {});
0N/A
0N/A // swap default with the first in the list
0N/A if (defaultIndex > 0) {
0N/A PrintService saveService = printServices[0];
0N/A printServices[0] = printServices[defaultIndex];
0N/A printServices[defaultIndex] = saveService;
0N/A }
0N/A }
0N/A
0N/A private boolean matchesAttributes(PrintService service,
0N/A PrintServiceAttributeSet attributes) {
0N/A
0N/A Attribute [] attrs = attributes.toArray();
0N/A Attribute serviceAttr;
0N/A for (int i=0; i<attrs.length; i++) {
0N/A serviceAttr
0N/A = service.getAttribute((Class<PrintServiceAttribute>)attrs[i].getCategory());
0N/A if (serviceAttr == null || !serviceAttr.equals(attrs[i])) {
0N/A return false;
0N/A }
0N/A }
0N/A return true;
0N/A }
0N/A
0N/A /* This checks for validity of the printer name before passing as
0N/A * parameter to a shell command.
0N/A */
0N/A private boolean checkPrinterName(String s) {
0N/A char c;
0N/A
0N/A for (int i=0; i < s.length(); i++) {
0N/A c = s.charAt(i);
0N/A if (Character.isLetterOrDigit(c) ||
0N/A c == '-' || c == '_' || c == '.' || c == '/') {
0N/A continue;
0N/A } else {
0N/A return false;
0N/A }
0N/A }
0N/A return true;
0N/A }
0N/A
0N/A /* On a network with many (hundreds) of network printers, it
0N/A * can save several seconds if you know all you want is a particular
0N/A * printer, to ask for that printer rather than retrieving all printers.
0N/A */
0N/A private PrintService getServiceByName(PrinterName nameAttr) {
0N/A String name = nameAttr.getValue();
0N/A if (name == null || name.equals("") || !checkPrinterName(name)) {
0N/A return null;
0N/A }
6150N/A /* check is all printers are already available */
6150N/A if (printServices != null) {
6150N/A for (PrintService printService : printServices) {
6150N/A if (printService.getName().equals(name)) {
6150N/A return printService;
6150N/A }
6150N/A }
6150N/A }
6150N/A /* take CUPS into account first */
6150N/A if (CUPSPrinter.isCupsRunning()) {
6150N/A try {
6150N/A return new IPPPrintService(name,
6150N/A new URL("http://"+
6150N/A CUPSPrinter.getServer()+":"+
6150N/A CUPSPrinter.getPort()+"/"+
6150N/A name));
6150N/A } catch (Exception e) {
6150N/A IPPPrintService.debug_println(debugPrefix+
6150N/A " getServiceByName Exception "+
6150N/A e);
6150N/A }
6150N/A }
6150N/A /* fallback if nothing not having a printer at this point */
6150N/A PrintService printer = null;
5145N/A if (isMac() || isSysV()) {
0N/A printer = getNamedPrinterNameSysV(name);
0N/A } else {
0N/A printer = getNamedPrinterNameBSD(name);
0N/A }
0N/A return printer;
0N/A }
0N/A
0N/A private PrintService[]
0N/A getPrintServices(PrintServiceAttributeSet serviceSet) {
0N/A
0N/A if (serviceSet == null || serviceSet.isEmpty()) {
0N/A return getPrintServices();
0N/A }
0N/A
0N/A /* Typically expect that if a service attribute is specified that
0N/A * its a printer name and there ought to be only one match.
0N/A * Directly retrieve that service and confirm
0N/A * that it meets the other requirements.
0N/A * If printer name isn't mentioned then go a slow path checking
0N/A * all printers if they meet the reqiremements.
0N/A */
0N/A PrintService[] services;
0N/A PrinterName name = (PrinterName)serviceSet.get(PrinterName.class);
0N/A PrintService defService;
0N/A if (name != null && (defService = getDefaultPrintService()) != null) {
0N/A /* To avoid execing a unix command see if the client is asking
0N/A * for the default printer by name, since we already have that
0N/A * initialised.
0N/A */
0N/A
0N/A PrinterName defName =
0N/A (PrinterName)defService.getAttribute(PrinterName.class);
0N/A
0N/A if (defName != null && name.equals(defName)) {
0N/A if (matchesAttributes(defService, serviceSet)) {
0N/A services = new PrintService[1];
0N/A services[0] = defService;
0N/A return services;
0N/A } else {
0N/A return new PrintService[0];
0N/A }
0N/A } else {
0N/A /* Its not the default service */
0N/A PrintService service = getServiceByName(name);
0N/A if (service != null &&
0N/A matchesAttributes(service, serviceSet)) {
0N/A services = new PrintService[1];
0N/A services[0] = service;
0N/A return services;
0N/A } else {
0N/A return new PrintService[0];
0N/A }
0N/A }
0N/A } else {
0N/A /* specified service attributes don't include a name.*/
0N/A Vector matchedServices = new Vector();
0N/A services = getPrintServices();
0N/A for (int i = 0; i< services.length; i++) {
0N/A if (matchesAttributes(services[i], serviceSet)) {
0N/A matchedServices.add(services[i]);
0N/A }
0N/A }
0N/A services = new PrintService[matchedServices.size()];
0N/A for (int i = 0; i< services.length; i++) {
0N/A services[i] = (PrintService)matchedServices.elementAt(i);
0N/A }
0N/A return services;
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * If service attributes are specified then there must be additional
0N/A * filtering.
0N/A */
0N/A public PrintService[] getPrintServices(DocFlavor flavor,
0N/A AttributeSet attributes) {
0N/A SecurityManager security = System.getSecurityManager();
0N/A if (security != null) {
0N/A security.checkPrintJobAccess();
0N/A }
0N/A PrintRequestAttributeSet requestSet = null;
0N/A PrintServiceAttributeSet serviceSet = null;
0N/A
0N/A if (attributes != null && !attributes.isEmpty()) {
0N/A
0N/A requestSet = new HashPrintRequestAttributeSet();
0N/A serviceSet = new HashPrintServiceAttributeSet();
0N/A
0N/A Attribute[] attrs = attributes.toArray();
0N/A for (int i=0; i<attrs.length; i++) {
0N/A if (attrs[i] instanceof PrintRequestAttribute) {
0N/A requestSet.add(attrs[i]);
0N/A } else if (attrs[i] instanceof PrintServiceAttribute) {
0N/A serviceSet.add(attrs[i]);
0N/A }
0N/A }
0N/A }
0N/A
0N/A PrintService[] services = getPrintServices(serviceSet);
0N/A if (services.length == 0) {
0N/A return services;
0N/A }
0N/A
0N/A if (CUPSPrinter.isCupsRunning()) {
0N/A ArrayList matchingServices = new ArrayList();
0N/A for (int i=0; i<services.length; i++) {
0N/A try {
0N/A if (services[i].
0N/A getUnsupportedAttributes(flavor, requestSet) == null) {
0N/A matchingServices.add(services[i]);
0N/A }
0N/A } catch (IllegalArgumentException e) {
0N/A }
0N/A }
0N/A services = new PrintService[matchingServices.size()];
0N/A return (PrintService[])matchingServices.toArray(services);
0N/A
0N/A } else {
0N/A // We only need to compare 1 PrintService because all
0N/A // UnixPrintServices are the same anyway. We will not use
0N/A // default PrintService because it might be null.
0N/A PrintService service = services[0];
0N/A if ((flavor == null ||
0N/A service.isDocFlavorSupported(flavor)) &&
0N/A service.getUnsupportedAttributes(flavor, requestSet) == null)
0N/A {
0N/A return services;
0N/A } else {
0N/A return new PrintService[0];
0N/A }
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * return empty array as don't support multi docs
0N/A */
0N/A public MultiDocPrintService[]
0N/A getMultiDocPrintServices(DocFlavor[] flavors,
0N/A AttributeSet attributes) {
0N/A SecurityManager security = System.getSecurityManager();
0N/A if (security != null) {
0N/A security.checkPrintJobAccess();
0N/A }
0N/A return new MultiDocPrintService[0];
0N/A }
0N/A
0N/A
0N/A public synchronized PrintService getDefaultPrintService() {
0N/A SecurityManager security = System.getSecurityManager();
0N/A if (security != null) {
0N/A security.checkPrintJobAccess();
0N/A }
0N/A
0N/A // clear defaultPrintService
0N/A defaultPrintService = null;
0N/A
0N/A IPPPrintService.debug_println("isRunning ? "+
0N/A (CUPSPrinter.isCupsRunning()));
0N/A if (CUPSPrinter.isCupsRunning()) {
0N/A defaultPrinter = CUPSPrinter.getDefaultPrinter();
0N/A } else {
5145N/A if (isMac() || isSysV()) {
0N/A defaultPrinter = getDefaultPrinterNameSysV();
0N/A } else {
0N/A defaultPrinter = getDefaultPrinterNameBSD();
0N/A }
0N/A }
0N/A if (defaultPrinter == null) {
0N/A return null;
0N/A }
0N/A defaultPrintService = null;
0N/A if (printServices != null) {
0N/A for (int j=0; j<printServices.length; j++) {
0N/A if (defaultPrinter.equals(printServices[j].getName())) {
0N/A defaultPrintService = printServices[j];
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A if (defaultPrintService == null) {
0N/A if (CUPSPrinter.isCupsRunning()) {
0N/A try {
0N/A PrintService defaultPS =
0N/A new IPPPrintService(defaultPrinter,
0N/A new URL("http://"+
0N/A CUPSPrinter.getServer()+":"+
0N/A CUPSPrinter.getPort()+"/"+
0N/A defaultPrinter));
0N/A defaultPrintService = defaultPS;
0N/A } catch (Exception e) {
0N/A }
0N/A } else {
0N/A defaultPrintService = new UnixPrintService(defaultPrinter);
0N/A }
0N/A }
0N/A
0N/A return defaultPrintService;
0N/A }
0N/A
0N/A public synchronized void
0N/A getServicesInbackground(BackgroundLookupListener listener) {
0N/A if (printServices != null) {
0N/A listener.notifyServices(printServices);
0N/A } else {
0N/A if (lookupListeners == null) {
0N/A lookupListeners = new Vector();
0N/A lookupListeners.add(listener);
0N/A Thread lookupThread = new Thread(this);
0N/A lookupThread.start();
0N/A } else {
0N/A lookupListeners.add(listener);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /* This method isn't used in most cases because we rely on code in
0N/A * javax.print.PrintServiceLookup. This is needed just for the cases
0N/A * where those interfaces are by-passed.
0N/A */
0N/A private PrintService[] copyOf(PrintService[] inArr) {
0N/A if (inArr == null || inArr.length == 0) {
0N/A return inArr;
0N/A } else {
0N/A PrintService []outArr = new PrintService[inArr.length];
0N/A System.arraycopy(inArr, 0, outArr, 0, inArr.length);
0N/A return outArr;
0N/A }
0N/A }
0N/A
0N/A public void run() {
0N/A PrintService[] services = getPrintServices();
0N/A synchronized (this) {
0N/A BackgroundLookupListener listener;
0N/A for (int i=0; i<lookupListeners.size(); i++) {
0N/A listener =
0N/A (BackgroundLookupListener)lookupListeners.elementAt(i);
0N/A listener.notifyServices(copyOf(services));
0N/A }
0N/A lookupListeners = null;
0N/A }
0N/A }
0N/A
0N/A private String getDefaultPrinterNameBSD() {
0N/A if (cmdIndex == UNINITIALIZED) {
0N/A cmdIndex = getBSDCommandIndex();
0N/A }
0N/A String[] names = execCmd(lpcFirstCom[cmdIndex]);
0N/A if (names == null || names.length == 0) {
0N/A return null;
0N/A }
0N/A
0N/A if ((cmdIndex==BSD_LPD_NG) &&
0N/A (names[0].startsWith("missingprinter"))) {
0N/A return null;
0N/A }
0N/A return names[0];
0N/A }
0N/A
0N/A private PrintService getNamedPrinterNameBSD(String name) {
0N/A if (cmdIndex == UNINITIALIZED) {
0N/A cmdIndex = getBSDCommandIndex();
0N/A }
0N/A String command = "/usr/sbin/lpc status " + name + lpcNameCom[cmdIndex];
0N/A String[] result = execCmd(command);
0N/A
0N/A if (result == null || !(result[0].equals(name))) {
0N/A return null;
0N/A }
0N/A return new UnixPrintService(name);
0N/A }
0N/A
0N/A private String[] getAllPrinterNamesBSD() {
0N/A if (cmdIndex == UNINITIALIZED) {
0N/A cmdIndex = getBSDCommandIndex();
0N/A }
0N/A String[] names = execCmd(lpcAllCom[cmdIndex]);
0N/A if (names == null || names.length == 0) {
0N/A return null;
0N/A }
0N/A return names;
0N/A }
0N/A
5145N/A static String getDefaultPrinterNameSysV() {
0N/A String defaultPrinter = "lp";
0N/A String command = "/usr/bin/lpstat -d";
0N/A
0N/A String [] names = execCmd(command);
0N/A if (names == null || names.length == 0) {
0N/A return defaultPrinter;
0N/A } else {
0N/A int index = names[0].indexOf(":");
0N/A if (index == -1 || (names[0].length() <= index+1)) {
0N/A return null;
0N/A } else {
0N/A String name = names[0].substring(index+1).trim();
0N/A if (name.length() == 0) {
0N/A return null;
0N/A } else {
0N/A return name;
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A private PrintService getNamedPrinterNameSysV(String name) {
0N/A
0N/A String command = "/usr/bin/lpstat -v " + name;
0N/A String []result = execCmd(command);
0N/A
0N/A if (result == null || result[0].indexOf("unknown printer") > 0) {
0N/A return null;
0N/A } else {
0N/A return new UnixPrintService(name);
0N/A }
0N/A }
0N/A
0N/A private String[] getAllPrinterNamesSysV() {
0N/A String defaultPrinter = "lp";
0N/A String command = "/usr/bin/lpstat -v|/usr/bin/expand|/usr/bin/cut -f3 -d' ' |/usr/bin/cut -f1 -d':' | /usr/bin/sort";
0N/A
0N/A String [] names = execCmd(command);
0N/A ArrayList printerNames = new ArrayList();
0N/A for (int i=0; i < names.length; i++) {
0N/A if (!names[i].equals("_default") &&
0N/A !names[i].equals(defaultPrinter) &&
0N/A !names[i].equals("")) {
0N/A printerNames.add(names[i]);
0N/A }
0N/A }
0N/A return (String[])printerNames.toArray(new String[printerNames.size()]);
0N/A }
0N/A
0N/A static String[] execCmd(final String command) {
0N/A ArrayList results = null;
0N/A try {
0N/A final String[] cmd = new String[3];
0N/A if (isSysV()) {
0N/A cmd[0] = "/usr/bin/sh";
0N/A cmd[1] = "-c";
0N/A cmd[2] = "env LC_ALL=C " + command;
0N/A } else {
0N/A cmd[0] = "/bin/sh";
0N/A cmd[1] = "-c";
0N/A cmd[2] = "LC_ALL=C " + command;
0N/A }
0N/A
0N/A results = (ArrayList)AccessController.doPrivileged(
0N/A new PrivilegedExceptionAction() {
0N/A public Object run() throws IOException {
0N/A
0N/A Process proc;
0N/A BufferedReader bufferedReader = null;
5089N/A File f = Files.createTempFile("prn","xc").toFile();
0N/A cmd[2] = cmd[2]+">"+f.getAbsolutePath();
0N/A
0N/A proc = Runtime.getRuntime().exec(cmd);
0N/A try {
0N/A boolean done = false; // in case of interrupt.
0N/A while (!done) {
0N/A try {
0N/A proc.waitFor();
0N/A done = true;
0N/A } catch (InterruptedException e) {
0N/A }
0N/A }
0N/A
0N/A if (proc.exitValue() == 0) {
0N/A FileReader reader = new FileReader(f);
0N/A bufferedReader = new BufferedReader(reader);
0N/A String line;
0N/A ArrayList results = new ArrayList();
0N/A while ((line = bufferedReader.readLine())
0N/A != null) {
0N/A results.add(line);
0N/A }
0N/A return results;
0N/A }
0N/A } finally {
0N/A f.delete();
0N/A // promptly close all streams.
0N/A if (bufferedReader != null) {
0N/A bufferedReader.close();
0N/A }
0N/A proc.getInputStream().close();
0N/A proc.getErrorStream().close();
0N/A proc.getOutputStream().close();
0N/A }
0N/A return null;
0N/A }
0N/A });
0N/A } catch (PrivilegedActionException e) {
0N/A }
0N/A if (results == null) {
0N/A return new String[0];
0N/A } else {
0N/A return (String[])results.toArray(new String[results.size()]);
0N/A }
0N/A }
0N/A
0N/A private class PrinterChangeListener extends Thread {
0N/A
0N/A public void run() {
0N/A int refreshSecs;
0N/A while (true) {
0N/A try {
0N/A refreshServices();
0N/A } catch (Exception se) {
0N/A IPPPrintService.debug_println(debugPrefix+"Exception in refresh thread.");
0N/A break;
0N/A }
0N/A
0N/A if ((printServices != null) &&
0N/A (printServices.length > minRefreshTime)) {
0N/A // compute new refresh time 1 printer = 1 sec
0N/A refreshSecs = printServices.length;
0N/A } else {
0N/A refreshSecs = minRefreshTime;
0N/A }
0N/A try {
0N/A sleep(refreshSecs * 1000);
0N/A } catch (InterruptedException e) {
0N/A break;
0N/A }
0N/A }
0N/A }
0N/A }
0N/A}