X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=scheduler%2Fcups-lpd.c;h=0da3d0c06e4e10ddcd446b87f261e8b6c15aa9a2;hb=4bc478876dcf088530811dc949861861f38cc292;hp=a2b0f90038e82156b8dcf625435a4676c3bee0cb;hpb=f7deaa1a21758ec90bf23314af018481ea8aea7f;p=thirdparty%2Fcups.git diff --git a/scheduler/cups-lpd.c b/scheduler/cups-lpd.c index a2b0f9003..0da3d0c06 100644 --- a/scheduler/cups-lpd.c +++ b/scheduler/cups-lpd.c @@ -1,53 +1,21 @@ /* - * "$Id: cups-lpd.c 6327 2007-03-12 14:32:10Z mike $" + * Line Printer Daemon interface for CUPS. * - * Line Printer Daemon interface for the Common UNIX Printing System (CUPS). + * Copyright 2007-2016 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. * - * Copyright 1997-2006 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Easy Software Products and are protected by Federal - * copyright law. Distribution and use rights are outlined in the file - * "LICENSE.txt" which should have been included with this file. If this - * file is missing or damaged please contact Easy Software Products - * at: - * - * Attn: CUPS Licensing Information - * Easy Software Products - * 44141 Airport View Drive, Suite 204 - * Hollywood, Maryland 20636 USA - * - * Voice: (301) 373-9600 - * EMail: cups-info@cups.org - * WWW: http://www.cups.org - * - * Contents: - * - * main() - Process an incoming LPD request... - * create_job() - Create a new print job. - * get_printer() - Get the named printer and its options. - * print_file() - Add a file to the current job. - * recv_print_job() - Receive a print job from the client. - * remove_jobs() - Cancel one or more jobs. - * send_state() - Send the queue state. - * smart_gets() - Get a line of text, removing the trailing CR and/or LF. + * Licensed under Apache License v2.0. See the file "LICENSE" for more information. */ /* * Include necessary headers... */ -#include -#include -#include -#include -#include -#include +#define _CUPS_NO_DEPRECATED +#include #include -#include #include #include - #include #include #include @@ -56,13 +24,9 @@ #ifdef HAVE_INTTYPES_H # include #endif /* HAVE_INTTYPES_H */ - -#ifdef HAVE_COREFOUNDATION_H -# include -#endif /* HAVE_COREFOUNDATION_H */ -#ifdef HAVE_CFPRIV_H -# include -#endif /* HAVE_CFPRIV_H */ +#ifdef __APPLE__ +# include +#endif /* __APPLE__ */ /* @@ -89,11 +53,9 @@ * Prototypes... */ -static int create_job(http_t *http, const char *dest, const char *title, - const char *user, int num_options, - cups_option_t *options); +static int create_job(http_t *http, const char *dest, const char *title, const char *user, int num_options, cups_option_t *options); static int get_printer(http_t *http, const char *name, char *dest, - int destsize, cups_option_t **options, + size_t destsize, cups_option_t **options, int *accepting, int *shared, ipp_pstate_t *state); static int print_file(http_t *http, int id, const char *filename, const char *docname, const char *user, @@ -105,6 +67,7 @@ static int remove_jobs(const char *name, const char *agent, static int send_state(const char *name, const char *list, int longstatus); static char *smart_gets(char *s, int len, FILE *fp); +static void smart_strlcpy(char *dst, const char *src, size_t dstsize); /* @@ -132,6 +95,10 @@ main(int argc, /* I - Number of command-line arguments */ int hostlookups; /* Do hostname lookups? */ +#ifdef __APPLE__ + xpc_transaction_begin(); +#endif /* __APPLE__ */ + /* * Don't buffer the output... */ @@ -157,6 +124,19 @@ main(int argc, /* I - Number of command-line arguments */ { switch (argv[i][1]) { + case 'h' : /* -h hostname[:port] */ + if (argv[i][2]) + cupsSetServer(argv[i] + 2); + else + { + i ++; + if (i < argc) + cupsSetServer(argv[i]); + else + syslog(LOG_WARNING, "Expected hostname string after -h option!"); + } + break; + case 'o' : /* Option */ if (argv[i][2]) num_defaults = cupsParseOptions(argv[i] + 2, num_defaults, @@ -194,7 +174,7 @@ main(int argc, /* I - Number of command-line arguments */ if (getpeername(0, (struct sockaddr *)&hostaddr, &hostlen)) { syslog(LOG_WARNING, "Unable to get client address - %s", strerror(errno)); - strcpy(hostname, "unknown"); + strlcpy(hostname, "unknown", sizeof(hostname)); } else { @@ -232,6 +212,11 @@ main(int argc, /* I - Number of command-line arguments */ syslog(LOG_ERR, "Unable to get command line from client!"); putchar(1); + +#ifdef __APPLE__ + xpc_transaction_end(); +#endif /* __APPLE__ */ + return (1); } @@ -240,14 +225,16 @@ main(int argc, /* I - Number of command-line arguments */ * resource list, and/or user name. */ - command = line[0]; - dest = line + 1; + if ((command = line[0]) == '\0') + dest = line; + else + dest = line + 1; if (command == 0x02) list = NULL; else { - for (list = dest + 1; *list && !isspace(*list & 255); list ++); + for (list = dest; *list && !isspace(*list & 255); list ++); while (isspace(*list & 255)) *list++ = '\0'; @@ -278,37 +265,42 @@ main(int argc, /* I - Number of command-line arguments */ syslog(LOG_INFO, "Receive print job for %s", dest); /* recv_print_job() sends initial status byte */ - status = recv_print_job(dest, num_defaults, defaults); + status = (char)recv_print_job(dest, num_defaults, defaults); break; case 0x03 : /* Send queue state (short) */ syslog(LOG_INFO, "Send queue state (short) for %s %s", dest, list); /* no status byte for this command */ - status = send_state(dest, list, 0); + status = (char)send_state(dest, list, 0); break; case 0x04 : /* Send queue state (long) */ syslog(LOG_INFO, "Send queue state (long) for %s %s", dest, list); /* no status byte for this command */ - status = send_state(dest, list, 1); + status = (char)send_state(dest, list, 1); break; case 0x05 : /* Remove jobs */ - /* - * Grab the agent and skip to the list of users and/or jobs. - */ + if (list) + { + /* + * Grab the agent and skip to the list of users and/or jobs. + */ - agent = list; + agent = list; - for (; *list && !isspace(*list & 255); list ++); - while (isspace(*list & 255)) - *list++ = '\0'; + for (; *list && !isspace(*list & 255); list ++); + while (isspace(*list & 255)) + *list++ = '\0'; - syslog(LOG_INFO, "Remove jobs %s on %s by %s", list, dest, agent); + syslog(LOG_INFO, "Remove jobs %s on %s by %s", list, dest, agent); - status = remove_jobs(dest, agent, list); + status = (char)remove_jobs(dest, agent, list); + } + else + status = 1; putchar(status); break; @@ -317,6 +309,10 @@ main(int argc, /* I - Number of command-line arguments */ syslog(LOG_INFO, "Closing connection"); closelog(); +#ifdef __APPLE__ + xpc_transaction_end(); +#endif /* __APPLE__ */ + return (status); } @@ -329,7 +325,7 @@ static int /* O - Job ID or -1 on error */ create_job(http_t *http, /* I - HTTP connection */ const char *dest, /* I - Destination name */ const char *title, /* I - job-name */ - const char *user, /* I - requesting-user-name */ + const char *user, /* I - requesting-user-name */ int num_options, /* I - Number of options for job */ cups_option_t *options) /* I - Options for job */ { @@ -344,7 +340,7 @@ create_job(http_t *http, /* I - HTTP connection */ * Setup the Create-Job request... */ - request = ippNewRequest(IPP_CREATE_JOB); + request = ippNewRequest(IPP_OP_CREATE_JOB); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", dest); @@ -355,7 +351,7 @@ create_job(http_t *http, /* I - HTTP connection */ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); - if (title) + if (title[0]) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, title); @@ -369,7 +365,7 @@ create_job(http_t *http, /* I - HTTP connection */ response = cupsDoRequest(http, request, uri); - if (!response || cupsLastError() > IPP_OK_CONFLICT) + if (!response || cupsLastError() > IPP_STATUS_OK_CONFLICTING) { syslog(LOG_ERR, "Unable to create job - %s", cupsLastErrorString()); @@ -409,7 +405,7 @@ static int /* O - Number of options or -1 on error */ get_printer(http_t *http, /* I - HTTP connection */ const char *name, /* I - Printer name from request */ char *dest, /* I - Destination buffer */ - int destsize, /* I - Size of destination buffer */ + size_t destsize, /* I - Size of destination buffer */ cups_option_t **options, /* O - Printer options */ int *accepting, /* O - printer-is-accepting-jobs value */ int *shared, /* O - printer-is-shared value */ @@ -445,19 +441,46 @@ get_printer(http_t *http, /* I - HTTP connection */ if (shared) *shared = 0; if (state) - *state = IPP_PRINTER_STOPPED; + *state = IPP_PSTATE_STOPPED; if (options) *options = NULL; /* - * If the queue name contains a space, lookup the printer-name using - * the printer-info value... + * See if the name is a queue name optionally with an instance name. + */ + + strlcpy(dest, name, destsize); + if ((value = strchr(dest, '/')) != NULL) + *value = '\0'; + + /* + * Setup the Get-Printer-Attributes request... + */ + + request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", dest); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", + (int)(sizeof(requested) / sizeof(requested[0])), + NULL, requested); + + /* + * Do the request... */ - if (strchr(name, ' ')) + response = cupsDoRequest(http, request, "/"); + + if (!response || cupsLastError() > IPP_STATUS_OK_CONFLICTING) { /* - * Lookup the printer-info... + * If we can't find the printer by name, look up the printer-name + * using the printer-info values... */ ipp_attribute_t *accepting_attr,/* printer-is-accepting-jobs */ @@ -467,11 +490,13 @@ get_printer(http_t *http, /* I - HTTP connection */ *state_attr; /* printer-state */ + ippDelete(response); + /* * Setup the CUPS-Get-Printers request... */ - request = ippNewRequest(CUPS_GET_PRINTERS); + request = ippNewRequest(IPP_OP_CUPS_GET_PRINTERS); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", @@ -484,7 +509,7 @@ get_printer(http_t *http, /* I - HTTP connection */ response = cupsDoRequest(http, request, "/"); - if (!response || cupsLastError() > IPP_OK_CONFLICT) + if (!response || cupsLastError() > IPP_STATUS_OK_CONFLICTING) { syslog(LOG_ERR, "Unable to get list of printers - %s", cupsLastErrorString()); @@ -545,7 +570,7 @@ get_printer(http_t *http, /* I - HTTP connection */ } if (info_attr && name_attr && - !strcasecmp(name, info_attr->values[0].string.text)) + !_cups_strcasecmp(name, info_attr->values[0].string.text)) { /* * Found a match, use this one! @@ -579,47 +604,6 @@ get_printer(http_t *http, /* I - HTTP connection */ } else { - /* - * Otherwise treat it as a queue name optionally with an instance name. - */ - - strlcpy(dest, name, destsize); - if ((value = strchr(dest, '/')) != NULL) - *value = '\0'; - - /* - * Setup the Get-Printer-Attributes request... - */ - - request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); - - httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, - "localhost", 0, "/printers/%s", dest); - - ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", - NULL, uri); - - ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, - "requested-attributes", - (int)(sizeof(requested) / sizeof(requested[0])), - NULL, requested); - - /* - * Do the request... - */ - - response = cupsDoRequest(http, request, "/"); - - if (!response || cupsLastError() > IPP_OK_CONFLICT) - { - syslog(LOG_ERR, "Unable to check printer status - %s", - cupsLastErrorString()); - - ippDelete(response); - - return (-1); - } - /* * Get values from the response... */ @@ -627,9 +611,9 @@ get_printer(http_t *http, /* I - HTTP connection */ if (accepting) { if ((attr = ippFindAttribute(response, "printer-is-accepting-jobs", - IPP_TAG_BOOLEAN)) == NULL) + IPP_TAG_BOOLEAN)) == NULL) syslog(LOG_ERR, "No printer-is-accepting-jobs attribute found in " - "response from server!"); + "response from server!"); else *accepting = attr->values[0].boolean; } @@ -637,10 +621,10 @@ get_printer(http_t *http, /* I - HTTP connection */ if (shared) { if ((attr = ippFindAttribute(response, "printer-is-shared", - IPP_TAG_BOOLEAN)) == NULL) + IPP_TAG_BOOLEAN)) == NULL) { syslog(LOG_ERR, "No printer-is-shared attribute found in " - "response from server!"); + "response from server!"); *shared = 1; } else @@ -650,9 +634,9 @@ get_printer(http_t *http, /* I - HTTP connection */ if (state) { if ((attr = ippFindAttribute(response, "printer-state", - IPP_TAG_ENUM)) == NULL) + IPP_TAG_ENUM)) == NULL) syslog(LOG_ERR, "No printer-state attribute found in " - "response from server!"); + "response from server!"); else *state = (ipp_pstate_t)attr->values[0].integer; } @@ -660,102 +644,6 @@ get_printer(http_t *http, /* I - HTTP connection */ ippDelete(response); } - /* - * Override shared value for LPD using system-specific APIs... - */ - -#ifdef HAVE_CFPRIV_H /* MacOS X */ - if (shared && *shared) - { - CFURLRef prefsurl; /* */ - CFDataRef xmldata; /* */ - CFPropertyListRef plist; /* */ - CFStringRef queueid; /* */ - CFArrayRef lprqarray; /* */ - CFBooleanRef serverflag; /* */ - Boolean prefsok; /* */ - static const char printerprefsfile[] = - "/Library/Preferences/com.apple.printservice.plist"; - /* Preferences file */ - - - /* - * See if we are running on MacOS X Server... - */ - - CFDictionaryRef versdict = _CFCopyServerVersionDictionary(); - - if (versdict) - { - /* - * Yes, use the LPR sharing preference... - */ - - CFRelease(versdict); - - *shared = 0; - - prefsurl = CFURLCreateFromFileSystemRepresentation( - kCFAllocatorDefault, - (const UInt8 *)printerprefsfile, - (CFIndex)strlen(printerprefsfile), - false); - if (prefsurl) - { - prefsok = CFURLCreateDataAndPropertiesFromResource( - kCFAllocatorDefault, prefsurl, &xmldata, - NULL, NULL, NULL); - if (prefsok) - { - plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, xmldata, - kCFPropertyListImmutable, NULL); - if (plist) - { - serverflag = (CFBooleanRef)CFDictionaryGetValue( - (CFDictionaryRef)plist, CFSTR("serviceState")); - - if (serverflag && CFBooleanGetValue(serverflag)) - { - lprqarray = (CFArrayRef)CFDictionaryGetValue( - (CFDictionaryRef)plist, CFSTR("lprSharedQueues")); - - if (lprqarray) - { - queueid = CFStringCreateWithCString(CFAllocatorGetDefault(), - dest, - kCFStringEncodingUTF8); - - if (queueid) - { - *shared = CFArrayContainsValue( - lprqarray, - CFRangeMake(0, CFArrayGetCount(lprqarray)), - queueid); - - CFRelease(queueid); - } - - CFRelease(lprqarray); - } - } - - if (serverflag) - CFRelease(serverflag); - - CFRelease(plist); - } - } - - CFRelease(prefsurl); - } - - if (!shared) - syslog(LOG_ERR, "Warning - Print Service sharing disabled for LPD " - "on queue: %s", name); - } - } -#endif /* HAVE_CFPRIV_H */ - /* * Next look for the printer in the lpoptions file... */ @@ -777,7 +665,7 @@ get_printer(http_t *http, /* I - HTTP connection */ * Make sure we have "Dest name options" or "Default name options"... */ - if ((strcasecmp(line, "Dest") && strcasecmp(line, "Default")) || !value) + if ((_cups_strcasecmp(line, "Dest") && _cups_strcasecmp(line, "Default")) || !value) continue; /* @@ -794,7 +682,7 @@ get_printer(http_t *http, /* I - HTTP connection */ * the loop - we're done! */ - if (!strcasecmp(value, name)) + if (!_cups_strcasecmp(value, name)) { num_options = cupsParseOptions(optptr, num_options, options); break; @@ -836,7 +724,7 @@ print_file(http_t *http, /* I - HTTP connection */ * Setup the Send-Document request... */ - request = ippNewRequest(IPP_SEND_DOCUMENT); + request = ippNewRequest(IPP_OP_SEND_DOCUMENT); snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); @@ -852,8 +740,7 @@ print_file(http_t *http, /* I - HTTP connection */ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, format); - if (last) - ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); + ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", (char)last); /* * Do the request... @@ -863,7 +750,7 @@ print_file(http_t *http, /* I - HTTP connection */ ippDelete(cupsDoFileRequest(http, request, uri, filename)); - if (cupsLastError() > IPP_OK_CONFLICT) + if (cupsLastError() > IPP_STATUS_OK_CONFLICTING) { syslog(LOG_ERR, "Unable to send document - %s", cupsLastErrorString()); @@ -890,7 +777,8 @@ recv_print_job( int fd; /* Temporary file */ FILE *fp; /* File pointer */ char filename[1024]; /* Temporary filename */ - int bytes; /* Bytes received */ + ssize_t bytes; /* Bytes received */ + size_t total; /* Total bytes */ char line[256], /* Line from file/stdin */ command, /* Command from line */ *count, /* Number of bytes */ @@ -917,7 +805,7 @@ recv_print_job( * Connect to the server... */ - http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); + http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL); if (!http) { syslog(LOG_ERR, "Unable to connect to server: %s", strerror(errno)); @@ -1023,7 +911,7 @@ recv_print_job( break; } - strcpy(filename, control); + strlcpy(filename, control, sizeof(filename)); } break; @@ -1059,7 +947,7 @@ recv_print_job( break; } - strcpy(filename, temp[num_data]); + strlcpy(filename, temp[num_data], sizeof(filename)); num_data ++; break; @@ -1074,15 +962,15 @@ recv_print_job( * Copy the data or control file from the client... */ - for (i = atoi(count); i > 0; i -= bytes) + for (total = (size_t)strtoll(count, NULL, 10); total > 0; total -= (size_t)bytes) { - if (i > sizeof(line)) - bytes = sizeof(line); + if (total > sizeof(line)) + bytes = (ssize_t)sizeof(line); else - bytes = i; + bytes = (ssize_t)total; - if ((bytes = fread(line, 1, bytes, stdin)) > 0) - bytes = write(fd, line, bytes); + if ((bytes = (ssize_t)fread(line, 1, (size_t)bytes, stdin)) > 0) + bytes = write(fd, line, (size_t)bytes); if (bytes < 1) { @@ -1148,9 +1036,10 @@ recv_print_job( * Grab the job information... */ - title[0] = '\0'; - user[0] = '\0'; - doccount = 0; + title[0] = '\0'; + user[0] = '\0'; + docname[0] = '\0'; + doccount = 0; while (smart_gets(line, sizeof(line), fp) != NULL) { @@ -1161,11 +1050,15 @@ recv_print_job( switch (line[0]) { case 'J' : /* Job name */ - strlcpy(title, line + 1, sizeof(title)); + smart_strlcpy(title, line + 1, sizeof(title)); break; + case 'N' : /* Document name */ + smart_strlcpy(docname, line + 1, sizeof(docname)); + break; + case 'P' : /* User identification */ - strlcpy(user, line + 1, sizeof(user)); + smart_strlcpy(user, line + 1, sizeof(user)); break; case 'L' : /* Print banner page */ @@ -1220,7 +1113,7 @@ recv_print_job( { syslog(LOG_WARNING, "No username specified by client! " "Using \"anonymous\"..."); - strcpy(user, "anonymous"); + strlcpy(user, "anonymous", sizeof(user)); } /* @@ -1249,7 +1142,7 @@ recv_print_job( switch (line[0]) { case 'N' : /* Document name */ - strlcpy(docname, line + 1, sizeof(docname)); + smart_strlcpy(docname, line + 1, sizeof(docname)); break; case 'c' : /* Plot CIF file */ @@ -1297,9 +1190,9 @@ recv_print_job( if (status) break; } - - fclose(fp); } + + fclose(fp); } } @@ -1341,8 +1234,7 @@ remove_jobs(const char *dest, /* I - Destination */ * Try connecting to the local server... */ - if ((http = httpConnectEncrypt(cupsServer(), ippPort(), - cupsEncryption())) == NULL) + if ((http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL)) == NULL) { syslog(LOG_ERR, "Unable to connect to server %s: %s", cupsServer(), strerror(errno)); @@ -1365,7 +1257,7 @@ remove_jobs(const char *dest, /* I - Destination */ list ++; /* - * Build an IPP_CANCEL_JOB request, which requires the following + * Build an IPP_OP_CANCEL_JOB request, which requires the following * attributes: * * attributes-charset @@ -1374,7 +1266,7 @@ remove_jobs(const char *dest, /* I - Destination */ * requesting-user-name */ - request = ippNewRequest(IPP_CANCEL_JOB); + request = ippNewRequest(IPP_OP_CANCEL_JOB); sprintf(uri, "ipp://localhost/jobs/%d", id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); @@ -1388,7 +1280,7 @@ remove_jobs(const char *dest, /* I - Destination */ ippDelete(cupsDoRequest(http, request, "/jobs")); - if (cupsLastError() > IPP_OK_CONFLICT) + if (cupsLastError() > IPP_STATUS_OK_CONFLICTING) { syslog(LOG_WARNING, "Cancel of job ID %d failed: %s\n", id, cupsLastErrorString()); @@ -1462,8 +1354,7 @@ send_state(const char *queue, /* I - Destination */ * Try connecting to the local server... */ - if ((http = httpConnectEncrypt(cupsServer(), ippPort(), - cupsEncryption())) == NULL) + if ((http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL)) == NULL) { syslog(LOG_ERR, "Unable to connect to server %s: %s", cupsServer(), strerror(errno)); @@ -1489,19 +1380,19 @@ send_state(const char *queue, /* I - Destination */ switch (state) { - case IPP_PRINTER_IDLE : + case IPP_PSTATE_IDLE : printf("%s is ready\n", dest); break; - case IPP_PRINTER_PROCESSING : + case IPP_PSTATE_PROCESSING : printf("%s is ready and printing\n", dest); break; - case IPP_PRINTER_STOPPED : + case IPP_PSTATE_STOPPED : printf("%s is not ready\n", dest); break; } /* - * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires + * Build an IPP_OP_GET_JOBS or IPP_OP_GET_JOB_ATTRIBUTES request, which requires * the following attributes: * * attributes-charset @@ -1511,7 +1402,7 @@ send_state(const char *queue, /* I - Destination */ id = atoi(list); - request = ippNewRequest(id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS); + request = ippNewRequest(id ? IPP_OP_GET_JOB_ATTRIBUTES : IPP_OP_GET_JOBS); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", dest); @@ -1540,7 +1431,7 @@ send_state(const char *queue, /* I - Destination */ jobcount = 0; response = cupsDoRequest(http, request, "/"); - if (cupsLastError() > IPP_OK_CONFLICT) + if (cupsLastError() > IPP_STATUS_OK_CONFLICTING) { printf("get-jobs failed: %s\n", cupsLastErrorString()); ippDelete(response); @@ -1569,7 +1460,7 @@ send_state(const char *queue, /* I - Destination */ jobid = 0; jobsize = 0; - jobstate = IPP_JOB_PENDING; + jobstate = IPP_JSTATE_PENDING; jobname = "untitled"; jobuser = NULL; jobdest = NULL; @@ -1630,8 +1521,8 @@ send_state(const char *queue, /* I - Destination */ * Display the job... */ - if (jobstate == IPP_JOB_PROCESSING) - strcpy(rankstr, "active"); + if (jobstate == IPP_JSTATE_PROCESSING) + strlcpy(rankstr, "active", sizeof(rankstr)); else { snprintf(rankstr, sizeof(rankstr), "%d%s", rank, ranks[rank % 10]); @@ -1712,7 +1603,7 @@ smart_gets(char *s, /* I - Pointer to line buffer */ break; } else if (ptr < end) - *ptr++ = ch; + *ptr++ = (char)ch; } *ptr = '\0'; @@ -1725,5 +1616,91 @@ smart_gets(char *s, /* I - Pointer to line buffer */ /* - * End of "$Id: cups-lpd.c 6327 2007-03-12 14:32:10Z mike $". + * 'smart_strlcpy()' - Copy a string and convert from ISO-8859-1 to UTF-8 as needed. */ + +static void +smart_strlcpy(char *dst, /* I - Output buffer */ + const char *src, /* I - Input string */ + size_t dstsize) /* I - Size of output buffer */ +{ + const unsigned char *srcptr; /* Pointer into input string */ + unsigned char *dstptr, /* Pointer into output buffer */ + *dstend; /* End of output buffer */ + int saw_8859 = 0; /* Saw an extended character that was not UTF-8? */ + + + for (srcptr = (unsigned char *)src, dstptr = (unsigned char *)dst, dstend = dstptr + dstsize - 1; *srcptr;) + { + if (*srcptr < 0x80) + *dstptr++ = *srcptr++; /* ASCII */ + else if (saw_8859) + { + /* + * Map ISO-8859-1 (most likely character set for legacy LPD clients) to + * UTF-8... + */ + + if (dstptr > (dstend - 2)) + break; + + *dstptr++ = 0xc0 | (*srcptr >> 6); + *dstptr++ = 0x80 | (*srcptr++ & 0x3f); + } + else if ((*srcptr & 0xe0) == 0xc0 && (srcptr[1] & 0xc0) == 0x80) + { + /* + * 2-byte UTF-8 sequence... + */ + + if (dstptr > (dstend - 2)) + break; + + *dstptr++ = *srcptr++; + *dstptr++ = *srcptr++; + } + else if ((*srcptr & 0xf0) == 0xe0 && (srcptr[1] & 0xc0) == 0x80 && (srcptr[2] & 0xc0) == 0x80) + { + /* + * 3-byte UTF-8 sequence... + */ + + if (dstptr > (dstend - 3)) + break; + + *dstptr++ = *srcptr++; + *dstptr++ = *srcptr++; + *dstptr++ = *srcptr++; + } + else if ((*srcptr & 0xf8) == 0xf0 && (srcptr[1] & 0xc0) == 0x80 && (srcptr[2] & 0xc0) == 0x80 && (srcptr[3] & 0xc0) == 0x80) + { + /* + * 4-byte UTF-8 sequence... + */ + + if (dstptr > (dstend - 4)) + break; + + *dstptr++ = *srcptr++; + *dstptr++ = *srcptr++; + *dstptr++ = *srcptr++; + *dstptr++ = *srcptr++; + } + else + { + /* + * Bad UTF-8 sequence, this must be an ISO-8859-1 string... + */ + + saw_8859 = 1; + + if (dstptr > (dstend - 2)) + break; + + *dstptr++ = 0xc0 | (*srcptr >> 6); + *dstptr++ = 0x80 | (*srcptr++ & 0x3f); + } + } + + *dstptr = '\0'; +}