Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8181571: printing to CUPS fails on mac sandbox app
Backport-of: 3d4be14eba60e21d5c10f2ad07a20c018329c563
  • Loading branch information
Alexander Scherbatiy committed May 24, 2022
1 parent f78c4bc commit fb234ac
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 9 deletions.
53 changes: 50 additions & 3 deletions src/java.desktop/unix/classes/sun/print/CUPSPrinter.java
Expand Up @@ -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
Expand All @@ -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 {
Expand All @@ -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();
}
}
Expand Down Expand Up @@ -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(), "");

Expand Down Expand Up @@ -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<Boolean>) () ->
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;
}
Expand Down
58 changes: 52 additions & 6 deletions src/java.desktop/unix/native/common/awt/CUPSfuncs.c
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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.
*
Expand Down

1 comment on commit fb234ac

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.