New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync with latest Apple backends #2086

Closed
michaelrsweet opened this Issue Nov 7, 2006 · 2 comments

Comments

Projects
None yet
1 participant
@michaelrsweet
Collaborator

michaelrsweet commented Nov 7, 2006

Version: 1.2-current
CUPS.org User: jlovell

Sync with latest Apple backends.

usb-darwin.c:
-When a class driver can't be loaded set the "apple-missing-usbclassdriver-error"
printer-state-reason and log a fatal error.

  • Fix serial number comparision when looking for a particular printer.
  • Trim whitespace characters from the device URI components make, model & serial# since we do the same to the 1284 strings before matching.

pap.c:

  • Use cupsBackendDeviceURI()
  • Use cupsBackChannelWrite() to send backchannel data.
  • Emit a legacy style announcement when listDevices() finds no devices.
  • Add connecting-to-device printer-state-reason.
  • Improved nbp_lookup() failure reporting.

Comments?

Thanks!

@michaelrsweet

This comment has been minimized.

Collaborator

michaelrsweet commented Nov 14, 2006

CUPS.org User: mike

Looks good; I removed the extra cups/http.h include in pap.c, since cups/cups.h includes it already...

@michaelrsweet

This comment has been minimized.

Collaborator

michaelrsweet commented Nov 14, 2006

"backend-sync.patch":

Index: backend/usb-darwin.c

--- backend/usb-darwin.c (revision 6073)
+++ backend/usb-darwin.c (working copy)
@@ -198,12 +198,13 @@
static void release_deviceinfo(CFStringRef _make, CFStringRef *model, CFStringRef *serial);
static kern_return_t load_classdriver(CFStringRef driverPath, printer_interface_t intf, classdriver_context_t *__driver);
static kern_return_t unload_classdriver(classdriver_context_t *__classDriver);
-static kern_return_t load_printerdriver(printer_data_t *printer);
-static kern_return_t registry_open(printer_data_t *printer);
+static kern_return_t load_printerdriver(printer_data_t *printer, CFStringRef *driverBundlePath);
+static kern_return_t registry_open(printer_data_t *printer, CFStringRef *driverBundlePath);
static kern_return_t registry_close(printer_data_t *printer);
static OSStatus copy_deviceid(classdriver_context_t *_printer, CFStringRef deviceID);
static void copy_devicestring(io_service_t usbInterface, CFStringRef *deviceID, UInt32 *deviceLocation);
static CFStringRef copy_value_for_key(CFStringRef deviceID, CFStringRef *keys);
+static CFStringRef cfstr_create_and_trim(const char *cstr);
static void parse_options(const char *options, char *serial, UInt32 *location, Boolean *waitEOF);
static void setup_cfLanguage(void);
static void *read_thread(void *reference);
@@ -255,6 +256,7 @@
int countdown = INITIAL_LOG_INTERVAL; /
Logging interval /
pthread_cond_t *readCompleteConditionPtr = NULL; /
Read complete condition /
pthread_mutex_t *readMutexPtr = NULL; /
Read mutex */

  • CFStringRef driverBundlePath; /* Class driver path */

setup_cfLanguage();
parse_options(options, serial, &printer_data.location, &printer_data.waitEOF);
@@ -263,9 +265,10 @@
resource++;

printer_data.uri = uri;

  • printer_data.make = CFStringCreateWithCString(NULL, hostname, kCFStringEncodingUTF8);
  • printer_data.model = CFStringCreateWithCString(NULL, resource, kCFStringEncodingUTF8);
  • printer_data.serial = CFStringCreateWithCString(NULL, serial, kCFStringEncodingUTF8);
  • printer_data.make = cfstr_create_and_trim(hostname);
  • printer_data.model = cfstr_create_and_trim(resource);
  • printer_data.serial = cfstr_create_and_trim(serial);

fputs("STATE: +connecting-to-device\n", stderr);

@@ -281,7 +284,9 @@
iterate_printers(find_device_callback, &printer_data);

 fprintf(stderr, "INFO: Opening Connection\n");
  • status = registry_open(&printer_data);
  • driverBundlePath = NULL;
  • status = registry_open(&printer_data, &driverBundlePath);
    #if defined(i386)
    /*
    * If we were unable to load the class drivers for this printer it's probably because they're ppc-only.
    @@ -292,7 +297,27 @@
    /* Never returns here /
    }
    #endif /
    i386 */
  • if (status == -2) {
  • /*
    
  •  \* If we still were unable to load the class drivers for this printer log
    
  •  \* the error and stop the queue...
    
  •  */
    
  •  if (driverBundlePath == NULL || !CFStringGetCString(driverBundlePath, buffer, sizeof(buffer), kCFStringEncodingUTF8))
    
  •    strlcpy(buffer, "USB class driver", sizeof(buffer));
    
  •  fprintf(stderr, "STATE: +apple-missing-usbclassdriver-error\n" \
    
  •         "FATAL: Could not load %s\n", buffer);
    
  •  if (driverBundlePath)
    
  • CFRelease(driverBundlePath);
  •  return CUPS_BACKEND_STOP;
    
  • }
  • if (driverBundlePath)

  •  CFRelease(driverBundlePath);
    

    if (status != noErr) {
    sleep( PRINTER_POLLING_INTERVAL );
    countdown -= PRINTER_POLLING_INTERVAL;
    @@ -508,7 +533,7 @@
    if (CFStringCompare(make, userData->make, kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
    if (CFStringCompare(model, userData->model, kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
    if (userData->serial != NULL) {

  •   if (serial != NULL && CFStringCompare(model, userData->model, kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
    
  •   if (serial != NULL && CFStringCompare(serial, userData->serial, kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
      IOObjectRetain(obj);
      userData->printerObj = obj;
      keepLooking = false;
    

    @@ -728,9 +753,11 @@

    /*

    • 'load_printerdriver()' - Load a vendor's (or generic) classdriver.
  • * If driverBundlePath is not NULL on return it is the callers responsbility to release it!
    */

-static kern_return_t load_printerdriver(printer_data_t _printer)
+static kern_return_t load_printerdriver(printer_data_t *printer, CFStringRef *driverBundlePath)
{
IOCFPlugInInterface *_iodev = NULL;
SInt32 score;
@@ -744,11 +771,10 @@

   kr = IORegistryEntryCreateCFProperties(printer->printerObj, &properties, NULL, kNilOptions);
   if (kr == kIOReturnSuccess) {
  • CFStringRef driverBundlePath = NULL;
    if (properties != NULL) {

  • driverBundlePath = (CFStringRef) CFDictionaryGetValue(properties, kUSBClassDriverProperty);
    
  • *driverBundlePath = (CFStringRef) CFDictionaryGetValue(properties, kUSBClassDriverProperty);
    

    }

  • kr = load_classdriver(driverBundlePath, intf, &printer->printerDriver);

  • kr = load_classdriver(*driverBundlePath, intf, &printer->printerDriver);
    }

    if (kr != kIOReturnSuccess)
    @@ -764,9 +790,9 @@

  • 'registry_open()' - Open a connection to the printer.
    */

-static kern_return_t registry_open(printer_data_t *printer)
+static kern_return_t registry_open(printer_data_t *printer, CFStringRef *driverBundlePath)
{

  • kern_return_t kr = load_printerdriver(printer);
  • kern_return_t kr = load_printerdriver(printer, driverBundlePath);
    if (kr != kIOReturnSuccess) {
    kr = -2;
    }
    @@ -975,6 +1001,27 @@
    }

+/*

  • * 'cfstr_create_and_trim()' - Create a CFString from a c-string and
  • * trim it's whitespace characters.
  • */
    +
    +CFStringRef cfstr_create_and_trim(const char *cstr)
    +{
  • CFStringRef cfstr;
  • CFMutableStringRef cfmutablestr = NULL;
  • if ((cfstr = CFStringCreateWithCString(NULL, cstr, kCFStringEncodingUTF8)) != NULL)
  • {
  • if ((cfmutablestr = CFStringCreateMutableCopy(NULL, 1024, cfstr)) != NULL)
  •  CFStringTrimWhitespace(cfmutablestr);
    
  • CFRelease(cfstr);
  • }
  • return (CFStringRef) cfmutablestr;
    +}

#pragma mark -
/*

  • 'parse_options()' - Parse uri options.
    @@ -1344,7 +1391,6 @@
    return NULL;
    }

/*

  • End of "$Id$".
    */
    Index: backend/pap.c

    --- backend/pap.c (revision 6073)
    +++ backend/pap.c (working copy)
    @@ -42,31 +42,35 @@
    • POSSIBILITY OF SUCH DAMAGE.
      *
      *
      -* This program implements the Printer Access Protocol (PAP) on top of AppleTalk Transaction
      -* Protocol (ATP). If it were to use the blocking pap functions of the AppleTalk library it
      -* would need seperate threads for reading, writing and status.
      +* This program implements the Printer Access Protocol (PAP) on top of AppleTalk
      +* Transaction Protocol (ATP). If it were to use the blocking pap functions of
      +* the AppleTalk library it would need seperate threads for reading, writing
      +* and status.
      *
    • Contents:
      *
    • main() - Send a file to the specified Appletalk printer.
    • listDevices() - List all LaserWriter printers in the local zone.
      -* printFile() - Print from a file descriptor to an NBP specified printer.
      +* printFile() - Print file.
    • papOpen() - Open a pap session to a printer.
      -* papClose() - Close a pap session after cleaning up pending transactions.
      +* papClose() - Close a pap session.
    • papWrite() - Write bytes to a printer.
      -* papCloseResp() - Send a pap close response in the rare case we receive a close connection request.
      +* 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 - Returns a string with any percent escape sequences replaced with their equivalent.
      +* 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 <config.h>
+
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
@@ -86,6 +90,8 @@
#include <netat/nbp.h>
#include <netat/pap.h>

+#include <cups/cups.h>
+#include <cups/backend.h>
#include <cups/http.h>

#include <libkern/OSByteOrder.h>
@@ -95,19 +101,25 @@
#else
/* These definitions come from at_proto.h... _/

define ZIP_DEF_INTERFACE NULL

-enum { RUNNING, NOTLOADED, LOADED, OTHERERROR }; /_ Appletalk Stack status Function. */
+enum { RUNNING, NOTLOADED, LOADED, OTHERERROR };

extern int atp_abort(int fd, at_inet_t *dest, u_short tid);
extern int atp_close(int fd);
-extern int atp_getreq(int fd, at_inet_t *src, char *buf, int *len, int *userdata, int *xo, u_short *tid, u_char *bitmap, int nowait);
+extern int atp_getreq(int fd, at_inet_t *src, char *buf, int *len, int *userdata,

  •         int *xo, u_short *tid, u_char *bitmap, int nowait);
    
    extern int atp_getresp(int fd, u_short *tid, at_resp_t *resp);
    extern int atp_look(int fd);
    extern int atp_open(at_socket *sock);
    -extern int atp_sendreq(int fd, at_inet_t *dest, char *buf, int len, int userdata, int xo, int xo_relt, u_short *tid, at_resp_t *resp, at_retry_t *retry, int nowait);
    -extern int atp_sendrsp(int fd, at_inet_t *dest, int xo, u_short tid, at_resp_t *resp);
    +extern int atp_sendreq(int fd, at_inet_t *dest, char *buf, int len,
  •          int userdata, int xo, int xo_relt, u_short *tid, 
    
  •          at_resp_t *resp, at_retry_t *retry, int nowait);
    
    +extern int atp_sendrsp(int fd, at_inet_t *dest, int xo, u_short tid,
  •          at_resp_t *resp);
    
    extern int checkATStack();
    -extern int nbp_lookup(at_entity_t *entity, at_nbptuple_t *buf, int max, at_retry_t *retry);
    -extern int nbp_make_entity(at_entity_t *entity, char *obj, char *type, char *zone);
    +extern int nbp_lookup(at_entity_t *entity, at_nbptuple_t *buf, int max,
  •         at_retry_t *retry);
    
    +extern int nbp_make_entity(at_entity_t *entity, char *obj, char *type,
  •          char _zone);
    
    extern int zip_getmyzone(char *ifName, at_nvestr_t *zone);
    #endif /_ HAVE_APPLETALK_AT_PROTO_H */

@@ -116,7 +128,7 @@
#include <CoreFoundation/CFPreferences.h>

/* Defines /
-#define MAX_PRINTERS 500 /
Max number of printers we can lookup in listDevices /
+#define MAX_PRINTERS 500 /
Max number of printers we can lookup */
#define PAP_CONNID 0
#define PAP_TYPE 1
#define PAP_EOF 2
@@ -126,43 +138,35 @@
#define SEQUENCE_NUM(p) (((u_char *)&p)[2])
#define IS_PAP_EOF(p) (((u_char *)&p)[2])

-#define PAPPacketStr(x) \

  • ((x) == AT_PAP_TYPE_OPEN_CONN) ? "PAP_OPEN_CONN" : \
  • ((x) == AT_PAP_TYPE_OPEN_CONN_REPLY) ? "PAP_OPEN_CONN_REPLY" : \
  • ((x) == AT_PAP_TYPE_SEND_DATA) ? "PAP_SEND_DATA" : \
  • ((x) == AT_PAP_TYPE_DATA) ? "PAP_DATA" : \
  • ((x) == AT_PAP_TYPE_TICKLE) ? "PAP_TICKLE" : \
  • ((x) == AT_PAP_TYPE_CLOSE_CONN) ? "PAP_CLOSE_CONN" : \
  • ((x) == AT_PAP_TYPE_CLOSE_CONN_REPLY) ? "PAP_CLOSE_CONN_REPLY" : \
  • ((x) == AT_PAP_TYPE_SEND_STATUS) ? "PAP_SEND_STATUS" : \
  • ((x) == AT_PAP_TYPE_SEND_STS_REPLY) ? "PAP_SEND_STS_REPLY" : \
  • ((x) == AT_PAP_TYPE_READ_LW) ? "PAP_READ_LW" : \

- ""

#ifndef true
#define true 1
#define false 0
#endif

/* Globals /
-int gSockfd = 0; /
Socket descriptor /
-at_inet_t gSessionAddr = { 0 }; /
Address of the session responding socket /
-u_char gConnID = 0; /
PAP session connection id /
-u_short gSendDataID = 0; /
Transaction id of our pending send-data request /
-u_short gTickleID = 0; /
Transaction id of our outstanding tickle request_/
-int gWaitEOF = false; /_ Option: causes us to wait for a remote's EOF /
+int gSockfd = 0; /
Socket descriptor /
+at_inet_t gSessionAddr = { 0 }; /
Address of the session responding socket /
+u_char gConnID = 0; /
PAP session connection id /
+u_short gSendDataID = 0; /
Transaction id of pending send-data request /
+u_short gTickleID = 0; /
Transaction id of outstanding tickle request_/
+int gWaitEOF = false; /_ Option: wait for a remote's EOF /
int gStatusInterval= 5; /
Option: 0=off else seconds between status requests_/
int gErrorlogged = false; /_ If an error was logged don't send any more INFO messages /
-int gDebug = 0; /
Option: causes us to emit debugging info /
+int gDebug = 0; /
Option: emit debugging info */

/* Local functions /
static int listDevices(void);
-static int printFile(char
name, char* type, char* zone, int fdin, int fdout, int fderr, int copies, int argc);
-static int papOpen(at_nbptuple_t* tuple, u_char* connID, int* fd, at_inet_t* pap_to, u_char* flowQuantum);
-static int papClose(int abortflag);
-static int papWrite(int sockfd, at_inet_t* dest, u_short tid, u_char connID, u_char flowQuantum, char* data, int len, int eof);
-static int papCloseResp(int sockfd, at_inet_t* dest, int xo, u_short tid, u_char connID);
-static int papSendRequest(int sockfd, at_inet_t* dest, u_char connID, int function, u_char bitmap, int xo, int seqno);
+static int printFile(char* name, char* type, char* zone, int fdin, int fdout,

  •        int fderr, int copies, int argc);
    
    +static int papOpen(at_nbptuple_t* tuple, u_char* connID, int* fd,
  •      at_inet_t\* pap_to, u_char\* flowQuantum);
    
    +static int papClose();
    +static int papWrite(int sockfd, at_inet_t* dest, u_short tid, u_char connID,
  •       u_char flowQuantum, char\* data, int len, int eof);
    
    +static int papCloseResp(int sockfd, at_inet_t* dest, int xo, u_short tid,
  •       u_char connID);
    
    +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 statusUpdate(char* status, u_char statusLen);
    static int parseUri(const char* argv0, char* name, char* type, char* zone);
    @@ -170,6 +174,7 @@
    static int removePercentEscapes(const char* src, char* dst, int dstMax);
    static int nbptuple_compare(const void *p1, const void *p2);
    static int okayToUseAppleTalk(void);
    +static const char *packet_name(u_char x);
    static int connectTimeout(void);
    static void signalHandler(int sigraised);

@@ -199,10 +204,13 @@

if (argc == 1 || (argc == 2 && strcmp(argv[1], "-discover") == 0))
{

  • /* Ignore errors returned by listDevices - they may be transitory
  • * and we don't want cupsd to think that pap is forever unusable.
  • /* If listDevices() didn't find any devices or returns an error output a
  • * legacy style announcement.
  • *
    */
  • listDevices();
  • if (listDevices() <= 0)
  •  puts("network pap \"Unknown\" \"AppleTalk Printer Access Protocol (pap)\"");
    
    return 0;
    }

@@ -239,9 +247,9 @@
}

/* Extract the device name and options from the URI... */

  • parseUri(argv[0], name, type, zone);
  • parseUri(cupsBackendDeviceURI((char **)argv), name, type, zone);
  • err = printFile(name, type, zone, fileno(fp), 3, STDERR_FILENO, copies, argc);
  • err = printFile(name, type, zone, fileno(fp), STDOUT_FILENO, STDERR_FILENO, copies, argc);

if (fp != stdin)
fclose(fp);
@@ -263,7 +271,7 @@
static int listDevices(void)
{
int err = noErr;

  • int ind;
  • int i;
    int numberFound;

at_nvestr_t at_zone;
@@ -287,11 +295,14 @@
perror("ERROR: Unable to get default AppleTalk zone");
return -2;
}
+
memcpy(zone, at_zone.str, MIN(at_zone.len, sizeof(zone)-1));
zone[MIN(at_zone.len, sizeof(zone)-1)] = '\0';

  • err = addPercentEscapes(zone, encodedZone, sizeof(encodedZone));
  • fprintf(stderr, "INFO: Using default AppleTalk zone "%s"\n", zone);
  • addPercentEscapes(zone, encodedZone, sizeof(encodedZone));

/* Look up all the printers in our zone /
nbp_make_entity(&entity, "=", "LaserWriter", zone);
retry.retries = 1;
@@ -310,10 +321,10 @@
/
Not required but sort them so they look nice */
qsort(buf, numberFound, sizeof(at_nbptuple_t), nbptuple_compare);

  • for (ind = 0; ind < numberFound; ind++)
  • for (i = 0; i < numberFound; i++)
    {
  • memcpy(name, buf[ind].enu_entity.object.str, MIN(buf[ind].enu_entity.object.len, sizeof(name)-1));
  • name[MIN(buf[ind].enu_entity.object.len, sizeof(name)-1)] = '\0';
  • memcpy(name, buf[i].enu_entity.object.str, MIN(buf[i].enu_entity.object.len, sizeof(name)-1));
  • name[MIN(buf[i].enu_entity.object.len, sizeof(name)-1)] = '\0';

if (addPercentEscapes(name, encodedName, sizeof(encodedName)) == 0)
{
@@ -371,7 +382,7 @@
int err;
int rc;
int val;

  • int len, ind;
  • int len, i;

char fileBuffer[4096]; /* File buffer */
int fileBufferNbytes;
@@ -390,21 +401,20 @@
int userdata, xo, reqlen;
u_short tid;
u_char bitmap;

  • int maxfdp1;
  • int maxfdp1,
  •   nbp_failures = 0;
    
    struct timeval timeout, *timeoutPtr;
    u_char flowQuantum = 1;
    u_short recvSequence = 0;
    time_t now,
  •   connect_time,
    
  •   start_time,
    elasped_time, 
    sleep_time,
    connect_timeout = -1,
    nextStatusTime = 0;
    
    at_entity_t entity;
    at_retry_t retry;
  • Boolean recoverableErrShown = false;

#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action; /* Actions for POSIX signals /
#endif /
HAVE_SIGACTION && !HAVE_SIGSET */
@@ -420,51 +430,60 @@

  • Remember when we started looking for the printer.
    */
  • connect_time = time(NULL);
  • start_time = time(NULL);

retry.interval = 1;
retry.retries = 5;
retry.backoff = 0;

  • fprintf(stderr, "STATE: +connecting-to-device\n");

/* Loop forever trying to get an open session with the printer. /
for (;;)
{
/
Make sure it's okay to use appletalk */
if (okayToUseAppleTalk())
{

  •  /\* Clear this printer-state-reason in case we've set it */
    
  •  fprintf(stderr, "STATE: -apple-appletalk-disabled-warning\n");
    
    • /* Resolve the name into an address. Returns the number found or an error */
      if ((err = nbp_lookup(&entity, &tuple, 1, &retry)) > 0)
      {
      if (err > 1)
      fprintf(stderr, "DEBUG: Found more than one printer with the name "%s"\n", name);
  • if (recoverableErrShown)

  • {

  • fprintf(stderr, "INFO: recovered: \n");
    
  • sleep(5);
    
  • recoverableErrShown = false;
    
  •    if (nbp_failures)
    
  •    {
    
  • fprintf(stderr, "STATE: -apple-nbp-lookup-warning\n");
    
  • nbp_failures = 0;
    

    }

     /* Open a connection to the device */
     if ((err = papOpen(&tuple, &gConnID, &gSockfd, &gSessionAddr, &flowQuantum)) == 0)
       break;
    
  •    fprintf(stderr, "WARNING: Unable to open \"%s:%s\": %s\n", name, zone, strerror(errno));
    
  •    fprintf(stderr, "WARNING: Unable to open \"%s:%s\": %s\n", name, zone, strerror(err));
    

    }
    else
    {

  • fprintf(stderr, "WARNING: recoverable: Printer not responding\n");

  • recoverableErrShown = true;

  • /* It's not unusual to have to call nbp_lookup() twice before it's sucessful... */

  •    if (++nbp_failures > 2)
    
  •    {
    
  • retry.interval = 2;
    
  • retry.retries = 3;
    
  • fprintf(stderr, "STATE: +apple-nbp-lookup-warning\n");
    
  • fprintf(stderr, "WARNING: Printer not responding\n");
    
  • }
    }
    }
    else
    {

  •  fprintf(stderr, "WARNING: recoverable: AppleTalk disabled in System Preferences.\n");
    
  •  recoverableErrShown = true;
    
  •  fprintf(stderr, "STATE: +apple-appletalk-disabled-warning\n");
    
  •  fprintf(stderr, "INFO: AppleTalk disabled in System Preferences.\n");
    

    }

  • retry.retries = 3;

  • elasped_time = time(NULL) - connect_time;

  • elasped_time = time(NULL) - start_time;

if (connect_timeout == -1)
connect_timeout = connectTimeout();
@@ -475,9 +494,9 @@
err = ETIMEDOUT;
goto Exit; /* Waiting too long... */
}

  • else if (elasped_time < 30 /(30 * 60)/)
  • else if (elasped_time < (30 * 60))
    sleep_time = 10; /* Waiting < 30 minutes */
  • else if (elasped_time < 60 /(24 * 60 * 60)/)
  • else if (elasped_time < (24 * 60 * 60))
    sleep_time = 30; /* Waiting < 24 hours /
    else
    sleep_time = 60; /
    Waiting > 24 hours */
    @@ -486,6 +505,8 @@
    sleep(sleep_time);
    }
  • fprintf(stderr, "STATE: -connecting-to-device\n");

/*

  • Now that we are connected to the printer ignore SIGTERM so that we
  • can finish out any page data the driver sends (e.g. to eject the
    @@ -536,21 +557,6 @@
    val = fcntl(fdin, F_GETFL, 0);
    fcntl(fdin, F_SETFL, val | O_NONBLOCK);
  • /* Set non-blocking mode on our data destination descriptor */
  • val = fcntl(fdout, F_GETFL, 0);
  • if (val < 0)
  • {
  • /*
  • * Map output to stdout if we don't have the backchannel pipe
  • * available on file descriptor 3...

- */

  • if (fdout == 3 && errno == EBADF)
  •  fdout = 1;
    
  • }
  • else

- fcntl(fdout, F_SETFL, val | O_NONBLOCK);

fileBufferNbytes = 0;
fileTbytes = 0;
fileEOFRead = fileEOFSent = false;
@@ -666,7 +672,7 @@
}
}

  •  fprintf(stderr, "DEBUG: <- %s\n", PAPPacketStr(TYPE_OF(userdata)));
    
  •  fprintf(stderr, "DEBUG: <- %s\n", packet_name(TYPE_OF(userdata)));
    

    switch (TYPE_OF(userdata))
    {
    @@ -707,10 +713,10 @@
    break;

    case AT_PAP_TYPE_DATA: /* Data packet */

  •    for (len=0, ind=0; ind < ATP_TRESP_MAX; ind++)
    
  •    for (len=0, i=0; i < ATP_TRESP_MAX; i++)
     {
    
  •      if (resp.bitmap & (1 << ind))
    
  •        len += resp.resp[ind].iov_len;
    
  •      if (resp.bitmap & (1 << i))
    
  •        len += resp.resp[i].iov_len;
     }
    
     fprintf(stderr, "DEBUG: <- PAP_DATA %d bytes %s\n", len, IS_PAP_EOF(userdata) ? "with EOF" : "");
    

    @@ -722,7 +728,7 @@
    char logstr[512];
    int logstrlen;

  • write(fdout, sockBuffer, len);
    
  • cupsBackChannelWrite(sockBuffer, len, 1.0);
    
       sockBuffer[len] = '\0';     /* We always reserve room for the nul so we can use strstr() below*/
       pLineBegin = sockBuffer;
    

    @@ -835,7 +841,7 @@
    /*

    • Close the socket and return...
      */
  • papClose(false);

  • papClose();

return err;
}
@@ -854,37 +860,35 @@
*

  • @Result A non-zero return value for errors
    /
    -static int papOpen(at_nbptuple_t
    tuple, u_char* connID, int* fd, at_inet_t* sessionAddr, u_char* flowQuantum)
    +static int papOpen(at_nbptuple_t* tuple, u_char* connID, int* fd,
  •      at_inet_t\* sessionAddr, u_char\* flowQuantum)
    
    {
    int result,
  •   openResult;
    
  • long tm;
  • char data[10], rdata[ATP_DATA_SIZE];
  • int userdata;
  • u_char *puserdata = (u_char *)&userdata;
  • at_socket sock = 0;
  • u_short waitTime;
  • int status;
  •   open_result,
    
  •   userdata,
    
  •   atp_err;
    
  • time_t tm,
  •   waitTime;
    
  • char data[10],
  •   rdata[ATP_DATA_SIZE];
    
  • u_char *puserdata;
  • at_socket socketfd;
    at_resp_t resp;
    at_retry_t retry;
  • if (tuple == NULL)
  • {
  • errno = EINVAL;
  • return -1;
  • }
  • result = 0;
  • socketfd = 0;
  • puserdata = (u_char *)&userdata;

fprintf(stderr, "INFO: Opening connection\n");

  • errno = 0;

- result = 0;

  • *fd = atp_open(&sock);
  • if (*fd < 0)
  • if ((*fd = atp_open(&socketfd)) < 0)
    return -1;
  • /* Build the open connection request packet.
  • /*
  • * Build the open connection request packet.
    */

tm = time(NULL);
srand(tm);

@@ -901,64 +905,67 @@
resp.resp[0].iov_base = rdata;
resp.resp[0].iov_len = sizeof(rdata);

  • data[0] = sock;
  • data[0] = socketfd;
    data[1] = 8;

for (;;)
{

  • waitTime = (u_short)(time(NULL) - tm);
  • OSWriteBigInt16(&data[2], 0, waitTime);
  • waitTime = time(NULL) - tm;
  • OSWriteBigInt16(&data[2], 0, (u_short)waitTime);
  • fprintf(stderr, "DEBUG: -> %s\n", PAPPacketStr(AT_PAP_TYPE_OPEN_CONN));
  • fprintf(stderr, "DEBUG: -> %s\n", packet_name(AT_PAP_TYPE_OPEN_CONN));

- status = atp_sendreq(*fd, &tuple->enu_addr, data, 4, userdata, 1, 0, 0, &resp, &retry, 0);

  • if (status < 0)
  • if ((atp_err = atp_sendreq(*fd, &tuple->enu_addr, data, 4, userdata, 1, 0,
  •              0, &resp, &retry, 0)) < 0)
    
    {
    statusUpdate("Destination unreachable", 23);
    result = EHOSTUNREACH;
  •  errno = EHOSTUNREACH;
    
  •  sleep(1);
    
  •  goto Exit;
    
  •  break;
    
    }
  • else
  • {
  •  puserdata = (u_char *)&resp.userdata[0];
    
  •  openResult = OSReadBigInt16(&rdata[2], 0);
    
  •  fprintf(stderr, "DEBUG: <- %s, status %d\n", PAPPacketStr(puserdata[1]), openResult);
    
  • puserdata = (u_char *)&resp.userdata[0];
  • open_result = OSReadBigInt16(&rdata[2], 0);
  •  /* Just for the sake of our sanity check the other fields in the packet
    
  •  */
    
  •  if (puserdata[1] != AT_PAP_TYPE_OPEN_CONN_REPLY ||
    
  •    (openResult == 0 && (puserdata[0] & 0xff) != *connID))
    
  •  {
    
  • result = EINVAL;
  • errno = EINVAL;
  • goto Exit;

- }

  •  statusUpdate(&rdata[5], rdata[4] & 0xff);
    
  • fprintf(stderr, "DEBUG: <- %s, status %d\n", packet_name(puserdata[1]),
  •   open_result);
    
  •  if (openResult == 0)
    
  • break; /* Connection established okay, exit from the loop */
  • /*
  • * Just for the sake of our sanity check the other fields in the packet
  • */
  • if (puserdata[1] != AT_PAP_TYPE_OPEN_CONN_REPLY ||

  • (open_result == 0 && (puserdata[0] & 0xff) != *connID))

  • {

  •  result = EINVAL;
    
  •  break;
    

    }

  • statusUpdate(&rdata[5], rdata[4] & 0xff);

  • /*
  • * if the connection established okay exit from the loop
  • */
  • if (open_result == 0)

  •  break;
    

    sleep(1);
    }

  • /* Update the session address

  • */

  • sessionAddr->net = tuple->enu_addr.net;

  • sessionAddr->node = tuple->enu_addr.node;

  • sessionAddr->socket = rdata[0];

- *flowQuantum = rdata[1];

-Exit:

  • if (result != 0)
  • if (result == 0)
    {
  • /* Update the session address
  • */
  • sessionAddr->net = tuple->enu_addr.net;
  • sessionAddr->node = tuple->enu_addr.node;
  • sessionAddr->socket = rdata[0];
  • *flowQuantum = rdata[1];
  • }
  • else
  • {
    atp_close(*fd);
    *fd = 0;
  • sleep(1);
    }

return result;
@@ -970,12 +977,9 @@

  • @abstract End a PAP session by canceling outstanding send-data & tickle
  •        transactions and sending a PAP close request.
    
  • * @param abort If we're aborting then send the close request
  • * with 0 retries (not yet implemented)
    • @Result A non-zero return value for errors
      */
      -static int papClose(int abortflag)
      +static int papClose()
      {
      int fd;
      u_short tmpID;
      @@ -1018,7 +1022,7 @@
      if (gWaitEOF == false)
      sleep(2);
  • fprintf(stderr, "DEBUG: -> %s\n", PAPPacketStr(AT_PAP_TYPE_CLOSE_CONN));
  • fprintf(stderr, "DEBUG: -> %s\n", packet_name(AT_PAP_TYPE_CLOSE_CONN));

puserdata[0] = gConnID;
puserdata[1] = AT_PAP_TYPE_CLOSE_CONN;
@@ -1058,7 +1062,7 @@
static int papWrite(int sockfd, at_inet_t* dest, u_short tid, u_char connID, u_char flowQuantum, char* data, int len, int eof)
{
int result;

  • int ind;
  • int i;
    u_char* puserdata;
    at_resp_t resp;

@@ -1076,26 +1080,26 @@

  • response packets to reply to an incoming

  • PAP 'SENDDATA' request
    */

    • for (ind = 0; ind < flowQuantum; ind++)
    • for (i = 0; i < flowQuantum; i++)
      {
    • resp.userdata[ind] = 0;
    • puserdata = (u_char *)&resp.userdata[ind];
    • resp.userdata[i] = 0;
    • puserdata = (u_char *)&resp.userdata[i];

    puserdata[PAP_CONNID] = connID;
    puserdata[PAP_TYPE] = AT_PAP_TYPE_DATA;
    puserdata[PAP_EOF] = eof ? 1 : 0;

  • resp.resp[ind].iov_base = (caddr_t)data;

  • resp.resp[i].iov_base = (caddr_t)data;

if (data)
data += AT_PAP_DATA_SIZE;

  • resp.resp[ind].iov_len = MIN((int)len, (int)AT_PAP_DATA_SIZE);
  • len -= resp.resp[ind].iov_len;
  • resp.resp[i].iov_len = MIN((int)len, (int)AT_PAP_DATA_SIZE);
  • len -= resp.resp[i].iov_len;
    if (len == 0)
    break;
    }
  • resp.bitmap = (1 << (ind + 1)) - 1;
  • resp.bitmap = (1 << (i + 1)) - 1;

/*

  • Write out the data as a PAP 'DATA' response
    @@ -1168,7 +1172,7 @@
    at_resp_t resp;
    static u_short pap_send_count = 0;
  • fprintf(stderr, "DEBUG: -> %s\n", PAPPacketStr(function));
  • fprintf(stderr, "DEBUG: -> %s\n", packet_name(function));

puserdata[0] = connID;
puserdata[1] = function;
@@ -1274,7 +1278,7 @@
/
static int parseUri(const char
argv0, char* name, char* type, char* zone)
{

  • char scheme[255], /* Scheme in URI */
  • char method[255], /* Method in URI /
    hostname[1024], /
    Hostname /
    username[255], /
    Username info (not used) /
    resource[1024], /
    Resource info (device and options) /
    @@ -1290,8 +1294,10 @@
    /
  • Extract the device name and options from the URI...
    */
  • method[0] = username[0] = hostname[0] = resource[0] = '\0';
  • port = 0;
  • httpSeparateURI(HTTP_URI_CODING_NONE, argv0, scheme, sizeof(scheme),
  • httpSeparateURI(HTTP_URI_CODING_NONE, argv0, method, sizeof(method),
    username, sizeof(username),
    hostname, sizeof(hostname), &port,
    resource, sizeof(resource));
    @@ -1528,6 +1534,31 @@

/*!

  • * @function packet_name
  • * @abstract Returns packet name string.
  • * @Result A string
  • */
    +static const char *packet_name(u_char x)
    +{
  • switch (x)
  • {
  • case AT_PAP_TYPE_OPEN_CONN: return "PAP_OPEN_CONN";
  • case AT_PAP_TYPE_OPEN_CONN_REPLY: return "PAP_OPEN_CONN_REPLY";
  • case AT_PAP_TYPE_SEND_DATA: return "PAP_SEND_DATA";
  • case AT_PAP_TYPE_DATA: return "PAP_DATA";
  • case AT_PAP_TYPE_TICKLE: return "PAP_TICKLE";
  • case AT_PAP_TYPE_CLOSE_CONN: return "PAP_CLOSE_CONN";
  • case AT_PAP_TYPE_CLOSE_CONN_REPLY: return "PAP_CLOSE_CONN_REPLY";
  • case AT_PAP_TYPE_SEND_STATUS: return "PAP_SEND_STATUS";
  • case AT_PAP_TYPE_SEND_STS_REPLY: return "PAP_SEND_STS_REPLY";
  • case AT_PAP_TYPE_READ_LW: return "PAP_READ_LW";
  • }
  • return "";
    +}

+/*!

  • @function connectTimeout
  • @abstract Returns the connect timeout preference value.
    */
    @@ -1562,7 +1593,7 @@
    {
    fprintf(stderr, "ERROR: There was a timeout error while sending data to the printer\n");
  • papClose(true);
  • papClose();

_exit(1);
}

@michaelrsweet michaelrsweet added this to the Stable milestone Mar 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment