From 9c8f20756301312428c21d7eef6c76d6c8f9defb Mon Sep 17 00:00:00 2001 From: AlexanderScherbatiy Date: Tue, 17 May 2022 14:43:38 +0300 Subject: [PATCH] Backport 3d4be14eba60e21d5c10f2ad07a20c018329c563 --- .../unix/classes/sun/print/CUPSPrinter.java | 53 ++++++++++++++++- .../unix/native/common/awt/CUPSfuncs.c | 58 +++++++++++++++++-- 2 files changed, 102 insertions(+), 9 deletions(-) diff --git a/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java b/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java index 404040e2d6b..b7715a87860 100644 --- a/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java +++ b/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java @@ -54,6 +54,7 @@ public class CUPSPrinter { private static native String getCupsServer(); private static native int getCupsPort(); private static native String getCupsDefaultPrinter(); + private static native String[] getCupsDefaultPrinters(); private static native boolean canConnect(String server, int port); private static native boolean initIDs(); // These functions need to be synchronized as @@ -78,6 +79,7 @@ public class CUPSPrinter { private static boolean libFound; private static String cupsServer = null; + private static String domainSocketPathname = null; private static int cupsPort = 0; static { @@ -92,6 +94,13 @@ public Void run() { libFound = initIDs(); if (libFound) { cupsServer = getCupsServer(); + // Is this a local domain socket pathname? + if (cupsServer != null && cupsServer.startsWith("/")) { + if (isSandboxedApp()) { + domainSocketPathname = cupsServer; + } + cupsServer = "localhost"; + } cupsPort = getCupsPort(); } } @@ -376,6 +385,20 @@ public OutputStream run() { * Get list of all CUPS printers using IPP. */ static String[] getAllPrinters() { + + if (getDomainSocketPathname() != null) { + String[] printerNames = getCupsDefaultPrinters(); + if (printerNames != null && printerNames.length > 0) { + String[] printerURIs = new String[printerNames.length]; + for (int i=0; i< printerNames.length; i++) { + printerURIs[i] = String.format("ipp://%s:%d/printers/%s", + getServer(), getPort(), printerNames[i]); + } + return printerURIs; + } + return null; + } + try { URL url = new URL("http", getServer(), getPort(), ""); @@ -458,15 +481,39 @@ public static int getPort() { return cupsPort; } + /** + * Returns CUPS domain socket pathname. + */ + private static String getDomainSocketPathname() { + return domainSocketPathname; + } + + @SuppressWarnings("removal") + private static boolean isSandboxedApp() { + if (PrintServiceLookupProvider.isMac()) { + return java.security.AccessController + .doPrivileged((java.security.PrivilegedAction) () -> + System.getenv("APP_SANDBOX_CONTAINER_ID") != null); + } + return false; + } + + /** * Detects if CUPS is running. */ public static boolean isCupsRunning() { IPPPrintService.debug_println(debugPrefix+"libFound "+libFound); if (libFound) { - IPPPrintService.debug_println(debugPrefix+"CUPS server "+getServer()+ - " port "+getPort()); - return canConnect(getServer(), getPort()); + String server = getDomainSocketPathname() != null + ? getDomainSocketPathname() + : getServer(); + IPPPrintService.debug_println(debugPrefix+"CUPS server "+server+ + " port "+getPort()+ + (getDomainSocketPathname() != null + ? " use domain socket pathname" + : "")); + return canConnect(server, getPort()); } else { return false; } diff --git a/src/java.desktop/unix/native/common/awt/CUPSfuncs.c b/src/java.desktop/unix/native/common/awt/CUPSfuncs.c index 62f57ffde5e..52677659ed3 100644 --- a/src/java.desktop/unix/native/common/awt/CUPSfuncs.c +++ b/src/java.desktop/unix/native/common/awt/CUPSfuncs.c @@ -172,12 +172,7 @@ Java_sun_print_CUPSPrinter_getCupsServer(JNIEnv *env, jstring cServer = NULL; const char* server = j2d_cupsServer(); if (server != NULL) { - // Is this a local domain socket? - if (strncmp(server, "/", 1) == 0) { - cServer = JNU_NewStringPlatform(env, "localhost"); - } else { - cServer = JNU_NewStringPlatform(env, server); - } + cServer = JNU_NewStringPlatform(env, server); } return cServer; } @@ -219,6 +214,57 @@ Java_sun_print_CUPSPrinter_getCupsDefaultPrinter(JNIEnv *env, return cDefPrinter; } +/* + * Returns list of default local printers + */ +JNIEXPORT jobjectArray JNICALL +Java_sun_print_CUPSPrinter_getCupsDefaultPrinters(JNIEnv *env, + jobject printObj) +{ + cups_dest_t *dests; + int i, j, num_dests; + jstring utf_str; + jclass cls; + jobjectArray nameArray = NULL; + + cls = (*env)->FindClass(env, "java/lang/String"); + CHECK_NULL_RETURN(cls, NULL); + + num_dests = j2d_cupsGetDests(&dests); + + if (dests == NULL) { + return NULL; + } + + nameArray = (*env)->NewObjectArray(env, num_dests, cls, NULL); + if (nameArray == NULL) { + j2d_cupsFreeDests(num_dests, dests); + DPRINTF("CUPSfuncs::bad alloc new array\n", "") + return NULL; + } + + for (i = 0; i < num_dests; i++) { + utf_str = JNU_NewStringPlatform(env, dests[i].name); + if (utf_str == NULL) { + for (j = i - 1; j >= 0; j--) { + utf_str = (*env)->GetObjectArrayElement(env, nameArray, j); + (*env)->SetObjectArrayElement(env, nameArray, j, NULL); + (*env)->DeleteLocalRef(env, utf_str); + utf_str = NULL; + } + j2d_cupsFreeDests(num_dests, dests); + (*env)->DeleteLocalRef(env, nameArray); + DPRINTF("CUPSfuncs::bad alloc new string ->name\n", "") + return NULL; + } + (*env)->SetObjectArrayElement(env, nameArray, i, utf_str); + (*env)->DeleteLocalRef(env, utf_str); + } + + j2d_cupsFreeDests(num_dests, dests); + return nameArray; +} + /* * Checks if connection can be made to the server. *