From a0574e50f1bd4f9e3909e1137cc4e54b32a7af9b Mon Sep 17 00:00:00 2001 From: mike Date: Mon, 18 Jun 2007 21:09:03 +0000 Subject: [PATCH] Merge Apple changes to pap backend and lpstat command (to show printer-state-reasons) More launchd changes. git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@6559 7a7537e8-13f0-0310-91df-b6672ffda945 --- backend/pap.c | 115 +++++++++++++++++++++++++++++------ init/org.cups.cups-lpd.plist | 2 + init/org.cups.cupsd.plist | 6 +- systemv/lpstat.c | 22 ++++++- 4 files changed, 121 insertions(+), 24 deletions(-) diff --git a/backend/pap.c b/backend/pap.c index bc7e0e17bd..bd43f6c9c2 100644 --- a/backend/pap.c +++ b/backend/pap.c @@ -49,24 +49,25 @@ * * Contents: * -* main() - Send a file to the specified Appletalk printer. -* listDevices() - List all LaserWriter printers in the local zone. -* printFile() - Print file. -* papOpen() - Open a pap session to a printer. -* papClose() - Close a pap session. -* papWrite() - Write bytes to a printer. -* papCloseResp() - Send a pap close response. -* papSendRequest() - Fomrat and send a pap packet. -* papCancelRequest() - Cancel a pending pap request. -* statusUpdate() - Print printer status to stderr. -* parseUri() - Extract the print name and zone from a uri. -* addPercentEscapes() - Encode a string with percent escapes. -* removePercentEscapes - Remove percent escape sequences from a string. -* nbptuple_compare() - Compare routine for qsort. -* okayToUseAppleTalk() - Returns true if AppleTalk is available and enabled. -* packet_name() - Returns packet name string. -* connectTimeout() - Returns the connect timeout preference value. -* signalHandler() - handle SIGINT to close the session before quiting. +* main() - Send a file to the specified Appletalk printer. +* listDevices() - List all LaserWriter printers in the local zone. +* printFile() - Print file. +* papOpen() - Open a pap session to a printer. +* papClose() - Close a pap session. +* papWrite() - Write bytes to a printer. +* papCloseResp() - Send a pap close response. +* papSendRequest() - Fomrat and send a pap packet. +* papCancelRequest() - Cancel a pending pap request. +* sidechannel_request() - Handle side-channel requests. +* statusUpdate() - Print printer status to stderr. +* parseUri() - Extract the print name and zone from a uri. +* addPercentEscapes() - Encode a string with percent escapes. +* removePercentEscapes - Remove percent escape sequences from a string. +* nbptuple_compare() - Compare routine for qsort. +* okayToUseAppleTalk() - Returns true if AppleTalk is available and enabled. +* packet_name() - Returns packet name string. +* connectTimeout() - Returns the connect timeout preference value. +* signalHandler() - handle SIGINT to close the session before quiting. */ #include @@ -92,6 +93,8 @@ #include #include +#include +#include #include @@ -167,6 +170,7 @@ static int papCloseResp(int sockfd, at_inet_t* dest, int xo, u_short tid, static int papSendRequest(int sockfd, at_inet_t* dest, u_char connID, int function, u_char bitmap, int xo, int seqno); static int papCancelRequest(int sockfd, u_short tid); +static void sidechannel_request(); static void statusUpdate(char* status, u_char statusLen); static int parseUri(const char* argv0, char* name, char* type, char* zone); static int addPercentEscapes(const char* src, char* dst, int dstMax); @@ -392,6 +396,7 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in char sockBuffer[4096 + 1]; /* Socket buffer with room for nul */ char atpReqBuf[AT_PAP_DATA_SIZE]; fd_set readSet; + int use_sidechannel; /* Use side channel? */ at_nbptuple_t tuple; at_inet_t sendDataAddr; @@ -418,6 +423,22 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in struct sigaction action; /* Actions for POSIX signals */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + /* + * Test the side channel descriptor before calling papOpen() since it may open + * an unused fd 4 (a.k.a. CUPS_SC_FD)... + */ + + FD_ZERO(&readSet); + FD_SET(CUPS_SC_FD, &readSet); + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + if ((select(CUPS_SC_FD+1, &readSet, NULL, NULL, &timeout)) >= 0) + use_sidechannel = 1; + else + use_sidechannel = 0; + /* try to find our printer */ if ((err = nbp_make_entity(&entity, name, type, zone)) != noErr) { @@ -559,8 +580,12 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in fileBufferNbytes = 0; fileTbytes = 0; fileEOFRead = fileEOFSent = false; + maxfdp1 = MAX(fdin, gSockfd) + 1; + if (use_sidechannel && CUPS_SC_FD >= maxfdp1) + maxfdp1 = CUPS_SC_FD + 1; + if (gStatusInterval != 0) { timeout.tv_usec = 0; @@ -580,6 +605,9 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in if (fileBufferNbytes == 0 && fileEOFRead == false) FD_SET(fdin, &readSet); + if (use_sidechannel) + FD_SET(CUPS_SC_FD, &readSet); + /* Set the select timeout value based on the next status interval */ if (gStatusInterval != 0) { @@ -604,6 +632,13 @@ static int printFile(char* name, char* type, char* zone, int fdin, int fdout, in nextStatusTime = time(NULL) + gStatusInterval; } + /* + * Check if we have a side-channel request ready... + */ + + if (use_sidechannel && FD_ISSET(CUPS_SC_FD, &readSet)) + sidechannel_request(); + /* Was there an event on the input stream? */ if (FD_ISSET(fdin, &readSet)) { @@ -1229,6 +1264,50 @@ int papCancelRequest(int sockfd, u_short tid) } +/* + * 'sidechannel_request()' - Handle side-channel requests. + */ + +static void +sidechannel_request() +{ + cups_sc_command_t command; /* Request command */ + cups_sc_status_t status; /* Request/response status */ + char data[2048]; /* Request/response data */ + int datalen; /* Request/response data size */ + + datalen = sizeof(data); + + if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) + { + fputs(_("WARNING: Failed to read side-channel request!\n"), stderr); + return; + } + + switch (command) + { + case CUPS_SC_CMD_GET_BIDI: /* Is the connection bidirectional? */ + data[0] = 1; + cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, 1, 1.0); + break; + + case CUPS_SC_CMD_GET_STATE: /* Return device state */ + data[0] = CUPS_SC_STATE_ONLINE; + cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, 1, 1.0); + break; + + case CUPS_SC_CMD_DRAIN_OUTPUT: /* Drain all pending output */ + case CUPS_SC_CMD_SOFT_RESET: /* Do a soft reset */ + case CUPS_SC_CMD_GET_DEVICE_ID: /* Return IEEE-1284 device ID */ + default: + cupsSideChannelWrite(command, CUPS_SC_STATUS_NOT_IMPLEMENTED, + NULL, 0, 1.0); + break; + } + return; +} + + #pragma mark - /*! * @function statusUpdate diff --git a/init/org.cups.cups-lpd.plist b/init/org.cups.cups-lpd.plist index f768e33388..9020d067ee 100644 --- a/init/org.cups.cups-lpd.plist +++ b/init/org.cups.cups-lpd.plist @@ -12,6 +12,8 @@ -o document-format=application/octet-stream + SHAuthorizationRight + system.preferences Sockets Listeners diff --git a/init/org.cups.cupsd.plist b/init/org.cups.cupsd.plist index 89bcab309f..74bcce6c3b 100644 --- a/init/org.cups.cupsd.plist +++ b/init/org.cups.cupsd.plist @@ -4,8 +4,6 @@ Label org.cups.cupsd - OnDemand - KeepAlive PathState @@ -14,8 +12,6 @@ - RunAtLoad - ProgramArguments /usr/sbin/cupsd @@ -23,6 +19,8 @@ ServiceIPC + SHAuthorizationRight + system.preferences Sockets Listeners diff --git a/systemv/lpstat.c b/systemv/lpstat.c index 867124cfe6..77b8675c30 100644 --- a/systemv/lpstat.c +++ b/systemv/lpstat.c @@ -1397,9 +1397,11 @@ show_jobs(http_t *http, /* I - HTTP connection to server */ int ranking, /* I - Show job ranking? */ const char *which) /* I - Show which jobs? */ { + int i; /* Looping var */ ipp_t *request, /* IPP Request */ *response; /* IPP Response */ - ipp_attribute_t *attr; /* Current attribute */ + ipp_attribute_t *attr, /* Current attribute */ + *reasons; /* Job state reasons attribute */ const char *dest, /* Pointer into job-printer-uri */ *username, /* Pointer to job-originating-user-name */ *title; /* Pointer to job-name */ @@ -1420,7 +1422,8 @@ show_jobs(http_t *http, /* I - HTTP connection to server */ "job-name", "time-at-creation", "job-printer-uri", - "job-originating-user-name" + "job-originating-user-name", + "job-state-reasons" }; @@ -1495,6 +1498,7 @@ show_jobs(http_t *http, /* I - HTTP connection to server */ dest = NULL; jobtime = 0; title = "no title"; + reasons = NULL; while (attr != NULL && attr->group_tag == IPP_TAG_JOB) { @@ -1523,6 +1527,10 @@ show_jobs(http_t *http, /* I - HTTP connection to server */ attr->value_tag == IPP_TAG_NAME) title = attr->values[0].string.text; + if (!strcmp(attr->name, "job-state-reasons") && + attr->value_tag == IPP_TAG_KEYWORD) + reasons = attr; + attr = attr->next; } @@ -1665,7 +1673,17 @@ show_jobs(http_t *http, /* I - HTTP connection to server */ temp, username ? username : "unknown", 1024.0 * size, date); if (long_status) + { + if (reasons) + { + _cupsLangPuts(stdout, _("\tAlerts:")); + for (i = 0; i < reasons->num_values; i ++) + _cupsLangPrintf(stdout, " %s", + reasons->values[i].string.text); + _cupsLangPuts(stdout, "\n"); + } _cupsLangPrintf(stdout, _("\tqueued for %s\n"), dest); + } } } -- 2.47.2