diff options
author | msweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be> | 2011-04-22 23:02:56 +0000 |
---|---|---|
committer | msweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be> | 2011-04-22 23:02:56 +0000 |
commit | 22c9029b44a790ba1ee894027431dcea1ec2aeab (patch) | |
tree | 20e787f4b9f7c9c574cf3450bf8326c83192fe39 /scheduler | |
parent | 07ed0e9a4385437b52e7195b681e600c2f1c5623 (diff) | |
download | cups-22c9029b44a790ba1ee894027431dcea1ec2aeab.tar.gz |
Merge changes from CUPS 1.5svn-r9717.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@3171 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'scheduler')
-rw-r--r-- | scheduler/client.c | 91 | ||||
-rw-r--r-- | scheduler/conf.c | 39 | ||||
-rw-r--r-- | scheduler/conf.h | 6 | ||||
-rw-r--r-- | scheduler/cups-deviced.c | 6 | ||||
-rw-r--r-- | scheduler/cups-driverd.cxx | 60 | ||||
-rw-r--r-- | scheduler/cups-exec.c | 20 | ||||
-rw-r--r-- | scheduler/cups-polld.c | 2 | ||||
-rw-r--r-- | scheduler/cupsd.h | 1 | ||||
-rw-r--r-- | scheduler/dirsvc.c | 12 | ||||
-rw-r--r-- | scheduler/filter.c | 170 | ||||
-rw-r--r-- | scheduler/ipp.c | 14 | ||||
-rw-r--r-- | scheduler/job.c | 96 | ||||
-rw-r--r-- | scheduler/listen.c | 13 | ||||
-rw-r--r-- | scheduler/log.c | 410 | ||||
-rw-r--r-- | scheduler/main.c | 15 | ||||
-rw-r--r-- | scheduler/mime.c | 269 | ||||
-rw-r--r-- | scheduler/network.c | 7 | ||||
-rw-r--r-- | scheduler/org.cups.cupsd.plist | 11 | ||||
-rw-r--r-- | scheduler/printers.c | 109 | ||||
-rw-r--r-- | scheduler/process.c | 108 | ||||
-rw-r--r-- | scheduler/testdirsvc.c | 4 | ||||
-rw-r--r-- | scheduler/testmime.c | 229 | ||||
-rw-r--r-- | scheduler/type.c | 150 | ||||
-rw-r--r-- | scheduler/util.c | 2 | ||||
-rw-r--r-- | scheduler/util.h | 2 |
25 files changed, 1166 insertions, 680 deletions
diff --git a/scheduler/client.c b/scheduler/client.c index 5db08bd39..2d8e171ae 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -179,29 +179,24 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */ return; } -#ifdef AF_INET6 - if (lis->address.addr.sa_family == AF_INET6) - { - /* - * Save the connected port number... - */ + /* + * Save the connected port number... + */ - con->http.hostaddr->ipv6.sin6_port = lis->address.ipv6.sin6_port; + _httpAddrSetPort(con->http.hostaddr, _httpAddrPort(&(lis->address))); - /* - * Convert IPv4 over IPv6 addresses (::ffff:n.n.n.n) to IPv4 forms we - * can more easily use... - */ +#ifdef AF_INET6 + /* + * Convert IPv4 over IPv6 addresses (::ffff:n.n.n.n) to IPv4 forms we + * can more easily use... + */ - if (con->http.hostaddr->ipv6.sin6_addr.s6_addr32[0] == 0 && - con->http.hostaddr->ipv6.sin6_addr.s6_addr32[1] == 0 && - ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2]) == 0xffff) - con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2] = 0; - } - else + if (lis->address.addr.sa_family == AF_INET6 && + con->http.hostaddr->ipv6.sin6_addr.s6_addr32[0] == 0 && + con->http.hostaddr->ipv6.sin6_addr.s6_addr32[1] == 0 && + ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2]) == 0xffff) + con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2] = 0; #endif /* AF_INET6 */ - if (lis->address.addr.sa_family == AF_INET) - con->http.hostaddr->ipv4.sin_port = lis->address.ipv4.sin_port; /* * Check the number of clients on the same address... @@ -357,22 +352,16 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */ } #endif /* HAVE_TCPD_H */ -#ifdef AF_INET6 - if (con->http.hostaddr->addr.sa_family == AF_INET6) - cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s:%d (IPv6)", - con->http.fd, con->http.hostname, - ntohs(con->http.hostaddr->ipv6.sin6_port)); - else -#endif /* AF_INET6 */ #ifdef AF_LOCAL if (con->http.hostaddr->addr.sa_family == AF_LOCAL) cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s (Domain)", con->http.fd, con->http.hostname); else #endif /* AF_LOCAL */ - cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s:%d (IPv4)", + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s:%d (IPv%d)", con->http.fd, con->http.hostname, - ntohs(con->http.hostaddr->ipv4.sin_port)); + _httpAddrPort(con->http.hostaddr), + _httpAddrFamily(con->http.hostaddr) == AF_INET ? 4 : 6); /* * Get the local address the client connected to... @@ -387,38 +376,23 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */ strcpy(con->servername, "localhost"); con->serverport = LocalPort; } +#ifdef AF_LOCAL + else if (_httpAddrFamily(&temp) == AF_LOCAL) + { + strcpy(con->servername, "localhost"); + con->serverport = LocalPort; + } +#endif /* AF_LOCAL */ else { -#ifdef AF_INET6 - if (temp.addr.sa_family == AF_INET6) - { - if (httpAddrLocalhost(&temp)) - strlcpy(con->servername, "localhost", sizeof(con->servername)); - else if (HostNameLookups || RemotePort) - httpAddrLookup(&temp, con->servername, sizeof(con->servername)); - else - httpAddrString(&temp, con->servername, sizeof(con->servername)); - - con->serverport = ntohs(lis->address.ipv6.sin6_port); - } + if (httpAddrLocalhost(&temp)) + strlcpy(con->servername, "localhost", sizeof(con->servername)); + else if (HostNameLookups || RemotePort) + httpAddrLookup(&temp, con->servername, sizeof(con->servername)); else -#endif /* AF_INET6 */ - if (temp.addr.sa_family == AF_INET) - { - if (httpAddrLocalhost(&temp)) - strlcpy(con->servername, "localhost", sizeof(con->servername)); - else if (HostNameLookups || RemotePort) - httpAddrLookup(&temp, con->servername, sizeof(con->servername)); - else - httpAddrString(&temp, con->servername, sizeof(con->servername)); + httpAddrString(&temp, con->servername, sizeof(con->servername)); - con->serverport = ntohs(lis->address.ipv4.sin_port); - } - else - { - strcpy(con->servername, "localhost"); - con->serverport = LocalPort; - } + con->serverport = _httpAddrPort(&(lis->address)); } cupsArrayAdd(Clients, con); @@ -3406,6 +3380,7 @@ encrypt_client(cupsd_client_t *con) /* I - Client to encrypt */ { cupsdLogMessage(CUPSD_LOG_DEBUG, "Received %d peer certificates!", (int)CFArrayGetCount(peerCerts)); + CFRelease(peerCerts); } else cupsdLogMessage(CUPSD_LOG_DEBUG, "Received NO peer certificates!"); @@ -3505,7 +3480,7 @@ get_cdsa_certificate( servername = CFStringCreateWithCString(kCFAllocatorDefault, localname, kCFStringEncodingUTF8); - + CFRelease(policy); policy = SecPolicyCreateSSL(1, servername); @@ -4591,7 +4566,7 @@ make_certificate(cupsd_client_t *con) /* I - Client connection */ } else servername = con->servername; - + /* * Run the "certtool" command to generate a self-signed certificate... */ diff --git a/scheduler/conf.c b/scheduler/conf.c index 8c0bd310b..fceede104 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -844,6 +844,19 @@ cupsdReadConfiguration(void) #endif /* HAVE_VSYSLOG */ /* + * Make sure each of the log files exists and gets rotated as necessary... + */ + + if (!strcmp(AccessLog, "syslog")) + cupsdCheckLogFile(&AccessFile, AccessLog); + + if (!strcmp(ErrorLog, "syslog")) + cupsdCheckLogFile(&ErrorFile, ErrorLog); + + if (!strcmp(PageLog, "syslog")) + cupsdCheckLogFile(&PageFile, PageLog); + + /* * Log the configuration file that was used... */ @@ -2618,29 +2631,17 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ httpAddrString(&lis->address, temp, sizeof(temp)); -#ifdef AF_INET6 - if (lis->address.addr.sa_family == AF_INET6) - cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d (IPv6)", temp, - ntohs(lis->address.ipv6.sin6_port)); - else -#endif /* AF_INET6 */ #ifdef AF_LOCAL if (lis->address.addr.sa_family == AF_LOCAL) cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s (Domain)", temp); else #endif /* AF_LOCAL */ - cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d (IPv4)", temp, - ntohs(lis->address.ipv4.sin_port)); + cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d (IPv%d)", temp, + _httpAddrPort(&(lis->address)), + _httpAddrFamily(&(lis->address)) == AF_INET ? 4 : 6); if (!httpAddrLocalhost(&(lis->address))) - { -#ifdef AF_INET6 - if (lis->address.addr.sa_family == AF_INET6) - RemotePort = ntohs(lis->address.ipv6.sin6_port); - else -#endif /* AF_INET6 */ - RemotePort = ntohs(lis->address.ipv4.sin_port); - } + RemotePort = _httpAddrPort(&(lis->address)); } /* @@ -2706,7 +2707,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ */ for (addr = addrlist; addr; addr = addr->next) - if (addr->addr.addr.sa_family == AF_INET) + if (_httpAddrFamily(&(addr->addr)) == AF_INET) break; if (addr) @@ -2716,7 +2717,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ cupsdLogMessage(CUPSD_LOG_INFO, "Sending browsing info to %s:%d (IPv4)", - temp, ntohs(dira->to.ipv4.sin_port)); + temp, _httpAddrPort(&(dira->to))); NumBrowsers ++; } @@ -3048,7 +3049,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ httpAddrString(&(relay->to), temp, sizeof(temp)); cupsdLogMessage(CUPSD_LOG_INFO, "Relaying from %s to %s:%d (IPv4)", - value, temp, ntohs(relay->to.ipv4.sin_port)); + value, temp, _httpAddrPort(&(relay->to))); NumRelays ++; } diff --git a/scheduler/conf.h b/scheduler/conf.h index 052725cce..4d669027a 100644 --- a/scheduler/conf.h +++ b/scheduler/conf.h @@ -3,7 +3,7 @@ * * Configuration file definitions for the CUPS scheduler. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -263,12 +263,16 @@ VAR char *SystemGroupAuthKey VALUE(NULL); */ extern void cupsdAddAlias(cups_array_t *aliases, const char *name); +extern int cupsdCheckLogFile(cups_file_t **lf, const char *logname); extern int cupsdCheckPermissions(const char *filename, const char *suffix, int mode, int user, int group, int is_dir, int create_dir); +extern int cupsdCheckProgram(const char *filename, cupsd_printer_t *p); extern void cupsdFreeAliases(cups_array_t *aliases); extern char *cupsdGetDateTime(struct timeval *t, cupsd_time_t format); +extern void cupsdLogFCMessage(void *context, _cups_fc_result_t result, + const char *message); #ifdef HAVE_GSSAPI extern int cupsdLogGSSMessage(int level, int major_status, int minor_status, diff --git a/scheduler/cups-deviced.c b/scheduler/cups-deviced.c index a7195985d..4e3df703a 100644 --- a/scheduler/cups-deviced.c +++ b/scheduler/cups-deviced.c @@ -3,7 +3,7 @@ * * Device scanning mini-daemon for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -767,6 +767,10 @@ start_backend(const char *name, /* I - Backend to run */ snprintf(program, sizeof(program), "%s/backend/%s", server_bin, name); + if (_cupsFileCheck(program, _CUPS_FILE_CHECK_PROGRAM, !geteuid(), + _cupsFileCheckFilter, NULL)) + return (-1); + backend = backends + num_backends; argv[0] = (char *)name; diff --git a/scheduler/cups-driverd.cxx b/scheduler/cups-driverd.cxx index 8f78df3b8..2bbc50a21 100644 --- a/scheduler/cups-driverd.cxx +++ b/scheduler/cups-driverd.cxx @@ -543,7 +543,10 @@ cat_static(const char *name, /* I - PPD name */ const char *datadir; /* CUPS_DATADIR env var */ char line[1024], /* Line/filename */ message[2048]; /* status-message */ - +#ifdef __APPLE__ + const char *printerDriver, /* Pointer to .printerDriver extension */ + *slash; /* Pointer to next slash */ +#endif /* __APPLE__ */ if (name[0] == '/' || strstr(name, "../") || strstr(name, "/..")) { @@ -575,7 +578,19 @@ cat_static(const char *name, /* I - PPD name */ #ifdef __APPLE__ if (!strncmp(name, "System/Library/Printers/PPDs/Contents/Resources/", 48) || - !strncmp(name, "Library/Printers/PPDs/Contents/Resources/", 41)) + !strncmp(name, "Library/Printers/PPDs/Contents/Resources/", 41) || + (!strncmp(name, "System/Library/Printers/", 24) && + (printerDriver = + strstr(name + 24, + ".printerDriver/Contents/Resources/PPDs")) != NULL && + (slash = strchr(name + 24, '/')) != NULL && + slash > printerDriver) || + (!strncmp(name, "Library/Printers/", 17) && + (printerDriver = + strstr(name + 17, + ".printerDriver/Contents/Resources/PPDs")) != NULL && + (slash = strchr(name + 17, '/')) != NULL && + slash > printerDriver)) { /* * Map ppd-name to Mac OS X standard locations... @@ -583,7 +598,6 @@ cat_static(const char *name, /* I - PPD name */ snprintf(line, sizeof(line), "/%s", name); } - else #elif defined(__linux) if (!strncmp(name, "lsb/usr/", 8)) @@ -872,10 +886,14 @@ list_ppds(int request_id, /* I - Request ID */ * Load PPDs from standard Mac OS X locations... */ + load_ppds("/Library/Printers", + "Library/Printers", 0); load_ppds("/Library/Printers/PPDs/Contents/Resources", "Library/Printers/PPDs/Contents/Resources", 0); load_ppds("/Library/Printers/PPDs/Contents/Resources/en.lproj", "Library/Printers/PPDs/Contents/Resources/en.lproj", 0); + load_ppds("/System/Library/Printers", + "System/Library/Printers", 0); load_ppds("/System/Library/Printers/PPDs/Contents/Resources", "System/Library/Printers/PPDs/Contents/Resources", 0); load_ppds("/System/Library/Printers/PPDs/Contents/Resources/en.lproj", @@ -1606,9 +1624,14 @@ load_drivers(cups_array_t *include, /* I - Drivers to include */ * Run the driver with no arguments and collect the output... */ - argv[0] = dent->filename; snprintf(filename, sizeof(filename), "%s/%s", drivers, dent->filename); + if (_cupsFileCheck(filename, _CUPS_FILE_CHECK_PROGRAM, !geteuid(), + _cupsFileCheckFilter, NULL)) + continue; + + argv[0] = dent->filename; + if ((fp = cupsdPipeCommand(&pid, filename, argv, 0)) != NULL) { while (cupsFileGets(fp, line, sizeof(line))) @@ -1807,6 +1830,14 @@ load_ppds(const char *d, /* I - Actual directory */ memcpy(dinfoptr, &dinfo, sizeof(struct stat)); cupsArrayAdd(Inodes, dinfoptr); + /* + * Check permissions... + */ + + if (_cupsFileCheck(d, _CUPS_FILE_CHECK_DIRECTORY, !geteuid(), + _cupsFileCheckFilter, NULL)) + return (0); + if ((dir = cupsDirOpen(d)) == NULL) { if (errno != ENOENT) @@ -1846,11 +1877,29 @@ load_ppds(const char *d, /* I - Actual directory */ */ if (descend) + { if (!load_ppds(filename, name, 1)) { cupsDirClose(dir); return (1); } + } + else if ((ptr = filename + strlen(filename) - 14) > filename && + !strcmp(ptr, ".printerDriver")) + { + /* + * Load PPDs in a printer driver bundle. + */ + + if (_cupsFileCheck(filename, _CUPS_FILE_CHECK_DIRECTORY, !geteuid(), + _cupsFileCheckFilter, NULL)) + continue; + + strlcat(filename, "/Contents/Resources/PPDs", sizeof(filename)); + strlcat(name, "/Contents/Resources/PPDs", sizeof(name)); + + load_ppds(filename, name, 0); + } continue; } @@ -1863,6 +1912,9 @@ load_ppds(const char *d, /* I - Actual directory */ continue; } + else if (_cupsFileCheck(filename, _CUPS_FILE_CHECK_FILE_ONLY, !geteuid(), + _cupsFileCheckFilter, NULL)) + continue; /* * See if this file has been scanned before... diff --git a/scheduler/cups-exec.c b/scheduler/cups-exec.c index 22bdd87a6..0081fb4c2 100644 --- a/scheduler/cups-exec.c +++ b/scheduler/cups-exec.c @@ -3,7 +3,7 @@ * * Sandbox helper for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * * These coded instructions, statements, and computer programs are the * property of Apple Inc. and are protected by Federal copyright @@ -40,6 +40,7 @@ int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { + int i; /* Looping var */ #ifdef HAVE_SANDBOX_H char *sandbox_error = NULL; /* Sandbox error, if any */ #endif /* HAVE_SANDBOX_H */ @@ -61,7 +62,8 @@ main(int argc, /* I - Number of command-line args */ * Run in a separate security profile... */ - if (sandbox_init(argv[1], SANDBOX_NAMED_EXTERNAL, &sandbox_error)) + if (strcmp(argv[1], "none") && + sandbox_init(argv[1], SANDBOX_NAMED_EXTERNAL, &sandbox_error)) { fprintf(stderr, "DEBUG: sandbox_init failed: %s (%s)\n", sandbox_error, strerror(errno)); @@ -71,6 +73,20 @@ main(int argc, /* I - Number of command-line args */ #endif /* HAVE_SANDBOX_H */ /* + * Close file descriptors we don't need (insurance): + * + * 0 = stdin + * 1 = stdout + * 2 = stderr + * 3 = back-channel + * 4 = side-channel + * 5-N = unused + */ + + for (i = 5; i < 1024; i ++) + close(i); + + /* * Execute the program... */ diff --git a/scheduler/cups-polld.c b/scheduler/cups-polld.c index cc4cbbbf0..d3ea64ef8 100644 --- a/scheduler/cups-polld.c +++ b/scheduler/cups-polld.c @@ -3,7 +3,7 @@ * * Polling daemon for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2006 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h index a443496e9..48fb32e8b 100644 --- a/scheduler/cupsd.h +++ b/scheduler/cupsd.h @@ -19,6 +19,7 @@ */ #include <cups/cups-private.h> +#include <cups/file-private.h> #include <limits.h> #include <time.h> diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c index ad05fe4c3..ca3c9cd8f 100644 --- a/scheduler/dirsvc.c +++ b/scheduler/dirsvc.c @@ -1594,16 +1594,8 @@ cupsdStartBrowsing(void) if (httpAddrLocalhost(&(lis->address))) continue; - if (lis->address.addr.sa_family == AF_INET) - { - DNSSDPort = ntohs(lis->address.ipv4.sin_port); - break; - } - else if (lis->address.addr.sa_family == AF_INET6) - { - DNSSDPort = ntohs(lis->address.ipv6.sin6_port); - break; - } + DNSSDPort = _httpAddrPort(&(lis->address)); + break; } /* diff --git a/scheduler/filter.c b/scheduler/filter.c index 9f734da56..b708fa368 100644 --- a/scheduler/filter.c +++ b/scheduler/filter.c @@ -3,7 +3,7 @@ * * File type conversion routines for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -14,14 +14,16 @@ * * Contents: * - * mimeAddFilter() - Add a filter to the current MIME database. - * mimeFilter() - Find the fastest way to convert from one type to - * another. - * mimeFilter2() - Find the fastest way to convert from one type to - * another, including the file size. - * mimeFilterLookup() - Lookup a filter. - * compare_filters() - Compare two filters. - * find_filters() - Find the filters to convert from one type to another. + * mimeAddFilter() - Add a filter to the current MIME database. + * mimeFilter() - Find the fastest way to convert from one type to + * another. + * mimeFilter2() - Find the fastest way to convert from one type to + * another, including the file size. + * mimeFilterLookup() - Lookup a filter. + * mime_compare_filters() - Compare two filters. + * mime_compare_srcs() - Compare two filter source types. + * mime_find_filters() - Find the filters to convert from one type to + * another. */ /* @@ -48,9 +50,9 @@ typedef struct _mime_typelist_s /**** List of source types ****/ * Local functions... */ -static int compare_filters(mime_filter_t *, mime_filter_t *); -static int compare_srcs(mime_filter_t *, mime_filter_t *); -static cups_array_t *find_filters(mime_t *mime, mime_type_t *src, +static int mime_compare_filters(mime_filter_t *, mime_filter_t *); +static int mime_compare_srcs(mime_filter_t *, mime_filter_t *); +static cups_array_t *mime_find_filters(mime_t *mime, mime_type_t *src, size_t srcsize, mime_type_t *dst, int *cost, _mime_typelist_t *visited); @@ -69,12 +71,21 @@ mimeAddFilter(mime_t *mime, /* I - MIME database */ mime_filter_t *temp; /* New filter */ + DEBUG_printf(("mimeAddFilter(mime=%p, src=%p(%s/%s), dst=%p(%s/%s), cost=%d, " + "filter=\"%s\")", mime, + src, src ? src->super : "???", src ? src->type : "???", + dst, dst ? dst->super : "???", dst ? dst->type : "???", + cost, filter)); + /* * Range-check the input... */ if (!mime || !src || !dst || !filter) + { + DEBUG_puts("1mimeAddFilter: Returning NULL."); return (NULL); + } /* * See if we already have an existing filter for the given source and @@ -90,6 +101,8 @@ mimeAddFilter(mime_t *mime, /* I - MIME database */ if (temp->cost > cost) { + DEBUG_printf(("1mimeAddFilter: Replacing filter \"%s\", cost %d.", + temp->filter, temp->cost)); temp->cost = cost; strlcpy(temp->filter, filter, sizeof(temp->filter)); } @@ -101,7 +114,7 @@ mimeAddFilter(mime_t *mime, /* I - MIME database */ */ if (!mime->filters) - mime->filters = cupsArrayNew((cups_array_func_t)compare_filters, NULL); + mime->filters = cupsArrayNew((cups_array_func_t)mime_compare_filters, NULL); if (!mime->filters) return (NULL); @@ -118,13 +131,17 @@ mimeAddFilter(mime_t *mime, /* I - MIME database */ temp->cost = cost; strlcpy(temp->filter, filter, sizeof(temp->filter)); + DEBUG_puts("1mimeAddFilter: Adding new filter."); cupsArrayAdd(mime->filters, temp); + cupsArrayAdd(mime->srcs, temp); } /* * Return the new/updated filter... */ + DEBUG_printf(("1mimeAddFilter: Returning %p.", temp)); + return (temp); } @@ -140,9 +157,9 @@ mimeFilter(mime_t *mime, /* I - MIME database */ int *cost) /* O - Cost of filters */ { DEBUG_printf(("mimeFilter(mime=%p, src=%p(%s/%s), dst=%p(%s/%s), " - "cost=%p(%d))", - mime, src, src ? src->super : "?", src ? src->type : "?", - dst, dst ? dst->super : "?", dst ? dst->type : "?", + "cost=%p(%d))", mime, + src, src ? src->super : "???", src ? src->type : "???", + dst, dst ? dst->super : "???", dst ? dst->type : "???", cost, cost ? *cost : 0)); return (mimeFilter2(mime, src, 0, dst, cost)); @@ -161,15 +178,19 @@ mimeFilter2(mime_t *mime, /* I - MIME database */ mime_type_t *dst, /* I - Destination file type */ int *cost) /* O - Cost of filters */ { + cups_array_t *filters; /* Array of filters to run */ + + /* * Range-check the input... */ DEBUG_printf(("mimeFilter2(mime=%p, src=%p(%s/%s), srcsize=" CUPS_LLFMT - ", dst=%p(%s/%s), cost=%p(%d))", - mime, src, src ? src->super : "?", src ? src->type : "?", - CUPS_LLCAST srcsize, dst, dst ? dst->super : "?", - dst ? dst->type : "?", cost, cost ? *cost : 0)); + ", dst=%p(%s/%s), cost=%p(%d))", mime, + src, src ? src->super : "???", src ? src->type : "???", + CUPS_LLCAST srcsize, + dst, dst ? dst->super : "???", dst ? dst->type : "???", + cost, cost ? *cost : 0)); if (cost) *cost = 0; @@ -185,7 +206,7 @@ mimeFilter2(mime_t *mime, /* I - MIME database */ { mime_filter_t *current; /* Current filter */ - mime->srcs = cupsArrayNew((cups_array_func_t)compare_srcs, NULL); + mime->srcs = cupsArrayNew((cups_array_func_t)mime_compare_srcs, NULL); for (current = mimeFirstFilter(mime); current; @@ -197,7 +218,24 @@ mimeFilter2(mime_t *mime, /* I - MIME database */ * Find the filters... */ - return (find_filters(mime, src, srcsize, dst, cost, NULL)); + filters = mime_find_filters(mime, src, srcsize, dst, cost, NULL); + + DEBUG_printf(("1mimeFilter2: Returning %d filter(s), cost %d:", + cupsArrayCount(filters), cost ? *cost : -1)); +#ifdef DEBUG + { + mime_filter_t *filter; /* Current filter */ + + for (filter = (mime_filter_t *)cupsArrayFirst(filters); + filter; + filter = (mime_filter_t *)cupsArrayNext(filters)) + DEBUG_printf(("1mimeFilter2: %s/%s %s/%s %d %s", filter->src->super, + filter->src->type, filter->dst->super, filter->dst->type, + filter->cost, filter->filter)); + } +#endif /* DEBUG */ + + return (filters); } @@ -210,23 +248,31 @@ mimeFilterLookup(mime_t *mime, /* I - MIME database */ mime_type_t *src, /* I - Source type */ mime_type_t *dst) /* I - Destination type */ { - mime_filter_t key; /* Key record for filter search */ + mime_filter_t key, /* Key record for filter search */ + *filter; /* Matching filter */ + + DEBUG_printf(("2mimeFilterLookup(mime=%p, src=%p(%s/%s), dst=%p(%s/%s))", mime, + src, src ? src->super : "???", src ? src->type : "???", + dst, dst ? dst->super : "???", dst ? dst->type : "???")); key.src = src; key.dst = dst; - return ((mime_filter_t *)cupsArrayFind(mime->filters, &key)); + filter = (mime_filter_t *)cupsArrayFind(mime->filters, &key); + DEBUG_printf(("3mimeFilterLookup: Returning %p(%s).", filter, + filter ? filter->filter : "???")); + return (filter); } /* - * 'compare_filters()' - Compare two filters. + * 'mime_compare_filters()' - Compare two filters. */ static int /* O - Comparison result */ -compare_filters(mime_filter_t *f0, /* I - First filter */ - mime_filter_t *f1) /* I - Second filter */ +mime_compare_filters(mime_filter_t *f0, /* I - First filter */ + mime_filter_t *f1) /* I - Second filter */ { int i; /* Result of comparison */ @@ -241,12 +287,12 @@ compare_filters(mime_filter_t *f0, /* I - First filter */ /* - * 'compare_srcs()' - Compare two srcs... + * 'mime_compare_srcs()' - Compare two filter source types. */ static int /* O - Comparison result */ -compare_srcs(mime_filter_t *f0, /* I - First filter */ - mime_filter_t *f1) /* I - Second filter */ +mime_compare_srcs(mime_filter_t *f0, /* I - First filter */ + mime_filter_t *f1) /* I - Second filter */ { int i; /* Result of comparison */ @@ -259,16 +305,17 @@ compare_srcs(mime_filter_t *f0, /* I - First filter */ /* - * 'find_filters()' - Find the filters to convert from one type to another. + * 'mime_find_filters()' - Find the filters to convert from one type to another. */ static cups_array_t * /* O - Array of filters to run */ -find_filters(mime_t *mime, /* I - MIME database */ - mime_type_t *src, /* I - Source file type */ - size_t srcsize, /* I - Size of source file */ - mime_type_t *dst, /* I - Destination file type */ - int *cost, /* O - Cost of filters */ - _mime_typelist_t *list) /* I - Source types we've used */ +mime_find_filters( + mime_t *mime, /* I - MIME database */ + mime_type_t *src, /* I - Source file type */ + size_t srcsize, /* I - Size of source file */ + mime_type_t *dst, /* I - Destination file type */ + int *cost, /* O - Cost of filters */ + _mime_typelist_t *list) /* I - Source types we've used */ { int tempcost, /* Temporary cost */ mincost; /* Current minimum */ @@ -280,7 +327,7 @@ find_filters(mime_t *mime, /* I - MIME database */ *listptr; /* Pointer in list */ - DEBUG_printf(("2find_filters(mime=%p, src=%p(%s/%s), srcsize=" CUPS_LLFMT + DEBUG_printf(("2mime_find_filters(mime=%p, src=%p(%s/%s), srcsize=" CUPS_LLFMT ", dst=%p(%s/%s), cost=%p, list=%p)", mime, src, src->super, src->type, CUPS_LLCAST srcsize, dst, dst->super, dst->type, cost, list)); @@ -296,20 +343,28 @@ find_filters(mime_t *mime, /* I - MIME database */ * Got a direct filter! */ - DEBUG_puts("2find_filters: Direct filter found!"); + DEBUG_puts("3mime_find_filters: Direct filter found."); if ((mintemp = cupsArrayNew(NULL, NULL)) == NULL) + { + DEBUG_puts("3mime_find_filters: Returning NULL (out of memory)."); return (NULL); + } cupsArrayAdd(mintemp, current); mincost = current->cost; if (!cost) + { + DEBUG_printf(("3mime_find_filters: Returning 1 filter, cost %d:", + mincost)); + DEBUG_printf(("3mime_find_filters: %s/%s %s/%s %d %s", + current->src->super, current->src->type, + current->dst->super, current->dst->type, + current->cost, current->filter)); return (mintemp); - - DEBUG_puts("2find_filters: Found direct filter:"); - DEBUG_printf(("2find_filters: %s (cost=%d)", current->filter, mincost)); + } } else { @@ -364,14 +419,30 @@ find_filters(mime_t *mime, /* I - MIME database */ listnode.src = current->src; cupsArraySave(mime->srcs); - temp = find_filters(mime, current->dst, srcsize, dst, &tempcost, &listnode); + temp = mime_find_filters(mime, current->dst, srcsize, dst, &tempcost, + &listnode); cupsArrayRestore(mime->srcs); if (!temp) continue; if (!cost) + { + DEBUG_printf(("3mime_find_filters: Returning %d filter(s), cost %d:", + cupsArrayCount(temp), tempcost)); + +#ifdef DEBUG + for (current = (mime_filter_t *)cupsArrayFirst(temp); + current; + current = (mime_filter_t *)cupsArrayNext(temp)) + DEBUG_printf(("3mime_find_filters: %s/%s %s/%s %d %s", + current->src->super, current->src->type, + current->dst->super, current->dst->type, + current->cost, current->filter)); +#endif /* DEBUG */ + return (temp); + } /* * Found a match; see if this one is less costly than the last (if @@ -403,14 +474,17 @@ find_filters(mime_t *mime, /* I - MIME database */ * Hey, we got a match! */ -#ifdef DEBUG - DEBUG_printf(("find_filters: Returning %d filters:\n", - cupsArrayCount(mintemp))); + DEBUG_printf(("3mime_find_filters: Returning %d filter(s), cost %d:", + cupsArrayCount(mintemp), mincost)); +#ifdef DEBUG for (current = (mime_filter_t *)cupsArrayFirst(mintemp); current; current = (mime_filter_t *)cupsArrayNext(mintemp)) - DEBUG_printf(("find_filters: %s\n", current->filter)); + DEBUG_printf(("3mime_find_filters: %s/%s %s/%s %d %s", + current->src->super, current->src->type, + current->dst->super, current->dst->type, + current->cost, current->filter)); #endif /* DEBUG */ if (cost) @@ -419,7 +493,7 @@ find_filters(mime_t *mime, /* I - MIME database */ return (mintemp); } - DEBUG_puts("find_filters: Returning zippo..."); + DEBUG_puts("3mime_find_filters: Returning NULL (no matches)."); return (NULL); } diff --git a/scheduler/ipp.c b/scheduler/ipp.c index d0011c03a..0d5e1eace 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -3106,6 +3106,12 @@ apple_init_profile( dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + if (!dict) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize profile \"%s\".", + iccfile); + return; + } cftext = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingUTF8); @@ -3286,7 +3292,12 @@ apple_register_profiles( strlcpy(iccfile, attr->value, sizeof(iccfile)); if (access(iccfile, 0)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "%s: ICC Profile \"%s\" does not exist.", p->name, + iccfile); continue; + } num_profiles ++; } @@ -3416,7 +3427,8 @@ apple_register_profiles( else strlcpy(iccfile, attr->value, sizeof(iccfile)); - if (access(iccfile, 0)) + if (_cupsFileCheck(iccfile, _CUPS_FILE_CHECK_FILE, !RunUser, + cupsdLogFCMessage, p)) continue; if (profile_key[0] == 'c') diff --git a/scheduler/job.c b/scheduler/job.c index 3d9c9e4e4..14b71231f 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -479,7 +479,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */ /* Job title string */ copies[255], /* # copies string */ *options, /* Options string */ - *envp[MAX_ENV + 19], + *envp[MAX_ENV + 20], /* Environment variables */ charset[255], /* CHARSET env variable */ class_name[255],/* CLASS env variable */ @@ -496,6 +496,8 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */ apple_language[255], /* APPLE_LANGUAGE env variable */ #endif /* __APPLE__ */ + auth_info_required[255], + /* AUTH_INFO_REQUIRED env variable */ ppd[1024], /* PPD env variable */ printer_info[255], /* PRINTER_INFO env variable */ @@ -878,6 +880,32 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */ snprintf(printer_name, sizeof(printer_name), "PRINTER=%s", job->printer->name); snprintf(rip_max_cache, sizeof(rip_max_cache), "RIP_MAX_CACHE=%s", RIPCache); + if (job->printer->num_auth_info_required == 1) + snprintf(auth_info_required, sizeof(auth_info_required), + "AUTH_INFO_REQUIRED=%s", + job->printer->auth_info_required[0]); + else if (job->printer->num_auth_info_required == 2) + snprintf(auth_info_required, sizeof(auth_info_required), + "AUTH_INFO_REQUIRED=%s,%s", + job->printer->auth_info_required[0], + job->printer->auth_info_required[1]); + else if (job->printer->num_auth_info_required == 3) + snprintf(auth_info_required, sizeof(auth_info_required), + "AUTH_INFO_REQUIRED=%s,%s,%s", + job->printer->auth_info_required[0], + job->printer->auth_info_required[1], + job->printer->auth_info_required[2]); + else if (job->printer->num_auth_info_required == 4) + snprintf(auth_info_required, sizeof(auth_info_required), + "AUTH_INFO_REQUIRED=%s,%s,%s,%s", + job->printer->auth_info_required[0], + job->printer->auth_info_required[1], + job->printer->auth_info_required[2], + job->printer->auth_info_required[3]); + else + strlcpy(auth_info_required, "AUTH_INFO_REQUIRED=none", + sizeof(auth_info_required)); + envc = cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0]))); envp[envc ++] = charset; @@ -938,6 +966,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */ envp[envc ++] = class_name; } + envp[envc ++] = auth_info_required; if (job->auth_username) envp[envc ++] = job->auth_username; if (job->auth_domain) @@ -1233,6 +1262,9 @@ void cupsdDeleteJob(cupsd_job_t *job, /* I - Job */ cupsd_jobaction_t action)/* I - Action */ { + char filename[1024]; /* Job filename */ + + if (job->printer) finalize_job(job, 1); @@ -1242,8 +1274,6 @@ cupsdDeleteJob(cupsd_job_t *job, /* I - Job */ * Remove the job info file... */ - char filename[1024]; /* Job filename */ - snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, job->id); unlink(filename); @@ -1261,7 +1291,14 @@ cupsdDeleteJob(cupsd_job_t *job, /* I - Job */ free(job->compressions); free(job->filetypes); - job->num_files = 0; + while (job->num_files > 0) + { + snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, + job->id, job->num_files); + unlink(filename); + + job->num_files --; + } } if (job->history) @@ -2946,6 +2983,57 @@ finalize_job(cupsd_job_t *job, /* I - Job */ message = "Job held for authentication."; } break; + + case CUPS_BACKEND_RETRY : + if (job_state == IPP_JOB_COMPLETED) + { + /* + * Hold the job if the number of retries is less than the + * JobRetryLimit, otherwise abort the job. + */ + + job->tries ++; + + if (job->tries > JobRetryLimit && JobRetryLimit > 0) + { + /* + * Too many tries... + */ + + snprintf(buffer, sizeof(buffer), + "Job aborted after %d unsuccessful attempts.", + JobRetryLimit); + job_state = IPP_JOB_ABORTED; + message = buffer; + } + else + { + /* + * Try again in N seconds... + */ + + snprintf(buffer, sizeof(buffer), + "Job held for %d seconds since it could not be sent.", + JobRetryInterval); + + job->hold_until = time(NULL) + JobRetryInterval; + job_state = IPP_JOB_HELD; + message = buffer; + } + } + break; + + case CUPS_BACKEND_RETRY_CURRENT : + /* + * Mark the job as pending and retry on the same printer... + */ + + if (job_state == IPP_JOB_COMPLETED) + { + job_state = IPP_JOB_PENDING; + message = "Retrying job on same printer."; + } + break; } } else if (job->status > 0) diff --git a/scheduler/listen.c b/scheduler/listen.c index 15af46f06..16528b9dd 100644 --- a/scheduler/listen.c +++ b/scheduler/listen.c @@ -151,18 +151,7 @@ cupsdStartListening(void) lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) { httpAddrString(&(lis->address), s, sizeof(s)); - -#ifdef AF_INET6 - if (lis->address.addr.sa_family == AF_INET6) - p = ntohs(lis->address.ipv6.sin6_port); - else -#endif /* AF_INET6 */ -#ifdef AF_LOCAL - if (lis->address.addr.sa_family == AF_LOCAL) - p = 0; - else -#endif /* AF_LOCAL */ - p = ntohs(lis->address.ipv4.sin_port); + p = _httpAddrPort(&(lis->address)); /* * If needed, create a socket for listening... diff --git a/scheduler/log.c b/scheduler/log.c index 4de1dc30c..aaea97ee9 100644 --- a/scheduler/log.c +++ b/scheduler/log.c @@ -14,6 +14,7 @@ * * Contents: * + * cupsdCheckLogFile() - Open/rotate a log file if it needs it. * cupsdGetDateTime() - Returns a pointer to a date/time string. * cupsdLogGSSMessage() - Log a GSSAPI error... * cupsdLogJob() - Log a job message. @@ -21,7 +22,6 @@ * cupsdLogPage() - Log a page to the page log file. * cupsdLogRequest() - Log an HTTP request in Common Log Format. * cupsdWriteErrorLog() - Write a line to the ErrorLog. - * check_log_file() - Open/rotate a log file if it needs it. * format_log_line() - Format a line for a log file. */ @@ -46,11 +46,188 @@ static char *log_line = NULL; /* Line for output file */ * Local functions... */ -static int check_log_file(cups_file_t **lf, const char *logname); static int format_log_line(const char *message, va_list ap); /* + * 'cupsdCheckLogFile()' - Open/rotate a log file if it needs it. + */ + +int /* O - 1 if log file open */ +cupsdCheckLogFile(cups_file_t **lf, /* IO - Log file */ + const char *logname) /* I - Log filename */ +{ + char backname[1024], /* Backup log filename */ + filename[1024], /* Formatted log filename */ + *ptr; /* Pointer into filename */ + const char *logptr; /* Pointer into log filename */ + + + /* + * See if we have a log file to check... + */ + + if (!lf || !logname || !logname[0]) + return (1); + + /* + * Format the filename as needed... + */ + + if (!*lf || + (strncmp(logname, "/dev/", 5) && cupsFileTell(*lf) > MaxLogSize && + MaxLogSize > 0)) + { + /* + * Handle format strings... + */ + + filename[sizeof(filename) - 1] = '\0'; + + if (logname[0] != '/') + { + strlcpy(filename, ServerRoot, sizeof(filename)); + strlcat(filename, "/", sizeof(filename)); + } + else + filename[0] = '\0'; + + for (logptr = logname, ptr = filename + strlen(filename); + *logptr && ptr < (filename + sizeof(filename) - 1); + logptr ++) + if (*logptr == '%') + { + /* + * Format spec... + */ + + logptr ++; + if (*logptr == 's') + { + /* + * Insert the server name... + */ + + strlcpy(ptr, ServerName, sizeof(filename) - (ptr - filename)); + ptr += strlen(ptr); + } + else + { + /* + * Otherwise just insert the character... + */ + + *ptr++ = *logptr; + } + } + else + *ptr++ = *logptr; + + *ptr = '\0'; + } + + /* + * See if the log file is open... + */ + + if (!*lf) + { + /* + * Nope, open the log file... + */ + + if ((*lf = cupsFileOpen(filename, "a")) == NULL) + { + /* + * If the file is in CUPS_LOGDIR then try to create a missing directory... + */ + + if (!strncmp(filename, CUPS_LOGDIR, strlen(CUPS_LOGDIR))) + { + /* + * Try updating the permissions of the containing log directory, using + * the log file permissions as a basis... + */ + + int log_dir_perm = 0300 | LogFilePerm; + /* LogFilePerm + owner write/search */ + if (log_dir_perm & 0040) + log_dir_perm |= 0010; /* Add group search */ + if (log_dir_perm & 0004) + log_dir_perm |= 0001; /* Add other search */ + + cupsdCheckPermissions(CUPS_LOGDIR, NULL, log_dir_perm, RunUser, Group, + 1, -1); + + *lf = cupsFileOpen(filename, "a"); + } + + if (*lf == NULL) + { + syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename, + strerror(errno)); + + if (FatalErrors & CUPSD_FATAL_LOG) + cupsdEndProcess(getpid(), 0); + + return (0); + } + } + + if (strncmp(filename, "/dev/", 5)) + { + /* + * Change ownership and permissions of non-device logs... + */ + + fchown(cupsFileNumber(*lf), RunUser, Group); + fchmod(cupsFileNumber(*lf), LogFilePerm); + } + } + + /* + * Do we need to rotate the log? + */ + + if (strncmp(logname, "/dev/", 5) && cupsFileTell(*lf) > MaxLogSize && + MaxLogSize > 0) + { + /* + * Rotate log file... + */ + + cupsFileClose(*lf); + + strcpy(backname, filename); + strlcat(backname, ".O", sizeof(backname)); + + unlink(backname); + rename(filename, backname); + + if ((*lf = cupsFileOpen(filename, "a")) == NULL) + { + syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename, + strerror(errno)); + + if (FatalErrors & CUPSD_FATAL_LOG) + cupsdEndProcess(getpid(), 0); + + return (0); + } + + /* + * Change ownership and permissions of non-device logs... + */ + + fchown(cupsFileNumber(*lf), RunUser, Group); + fchmod(cupsFileNumber(*lf), LogFilePerm); + } + + return (1); +} + + +/* * 'cupsdGetDateTime()' - Returns a pointer to a date/time string. */ @@ -135,6 +312,51 @@ cupsdGetDateTime(struct timeval *t, /* I - Time value or NULL for current */ } +/* + * 'cupsdLogFCMessage()' - Log a file checking message. + */ + +void +cupsdLogFCMessage( + void *context, /* I - Printer (if any) */ + _cups_fc_result_t result, /* I - Check result */ + const char *message) /* I - Message to log */ +{ + cupsd_printer_t *p = (cupsd_printer_t *)context; + /* Printer */ + cupsd_loglevel_t level; /* Log level */ + + + if (result == _CUPS_FILE_CHECK_OK) + level = CUPSD_LOG_DEBUG2; + else + level = CUPSD_LOG_ERROR; + + if (p) + { + cupsdLogMessage(level, "%s: %s", p->name, message); + + if (result == _CUPS_FILE_CHECK_MISSING || + result == _CUPS_FILE_CHECK_WRONG_TYPE) + { + strlcpy(p->state_message, message, sizeof(p->state_message)); + + if (cupsdSetPrinterReasons(p, "+cups-missing-filter-warning")) + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, p, NULL, "%s", message); + } + else if (result == _CUPS_FILE_CHECK_PERMISSIONS) + { + strlcpy(p->state_message, message, sizeof(p->state_message)); + + if (cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning")) + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, p, NULL, "%s", message); + } + } + else + cupsdLogMessage(level, "%s", message); +} + + #ifdef HAVE_GSSAPI /* * 'cupsdLogGSSMessage()' - Log a GSSAPI error... @@ -508,7 +730,7 @@ cupsdLogPage(cupsd_job_t *job, /* I - Job being printed */ * Not using syslog; check the log file... */ - if (!check_log_file(&PageFile, PageLog)) + if (!cupsdCheckLogFile(&PageFile, PageLog)) return (0); /* @@ -687,7 +909,7 @@ cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */ * Not using syslog; check the log file... */ - if (!check_log_file(&AccessFile, AccessLog)) + if (!cupsdCheckLogFile(&AccessFile, AccessLog)) return (0); /* @@ -769,7 +991,7 @@ cupsdWriteErrorLog(int level, /* I - Log level */ * Not using syslog; check the log file... */ - if (!check_log_file(&ErrorFile, ErrorLog)) + if (!cupsdCheckLogFile(&ErrorFile, ErrorLog)) return (0); /* @@ -785,184 +1007,6 @@ cupsdWriteErrorLog(int level, /* I - Log level */ /* - * 'check_log_file()' - Open/rotate a log file if it needs it. - */ - -static int /* O - 1 if log file open */ -check_log_file(cups_file_t **lf, /* IO - Log file */ - const char *logname) /* I - Log filename */ -{ - char backname[1024], /* Backup log filename */ - filename[1024], /* Formatted log filename */ - *ptr; /* Pointer into filename */ - const char *logptr; /* Pointer into log filename */ - - - /* - * See if we have a log file to check... - */ - - if (!lf || !logname || !logname[0]) - return (1); - - /* - * Format the filename as needed... - */ - - if (!*lf || - (strncmp(logname, "/dev/", 5) && cupsFileTell(*lf) > MaxLogSize && - MaxLogSize > 0)) - { - /* - * Handle format strings... - */ - - filename[sizeof(filename) - 1] = '\0'; - - if (logname[0] != '/') - { - strlcpy(filename, ServerRoot, sizeof(filename)); - strlcat(filename, "/", sizeof(filename)); - } - else - filename[0] = '\0'; - - for (logptr = logname, ptr = filename + strlen(filename); - *logptr && ptr < (filename + sizeof(filename) - 1); - logptr ++) - if (*logptr == '%') - { - /* - * Format spec... - */ - - logptr ++; - if (*logptr == 's') - { - /* - * Insert the server name... - */ - - strlcpy(ptr, ServerName, sizeof(filename) - (ptr - filename)); - ptr += strlen(ptr); - } - else - { - /* - * Otherwise just insert the character... - */ - - *ptr++ = *logptr; - } - } - else - *ptr++ = *logptr; - - *ptr = '\0'; - } - - /* - * See if the log file is open... - */ - - if (!*lf) - { - /* - * Nope, open the log file... - */ - - if ((*lf = cupsFileOpen(filename, "a")) == NULL) - { - /* - * If the file is in CUPS_LOGDIR then try to create a missing directory... - */ - - if (!strncmp(filename, CUPS_LOGDIR, strlen(CUPS_LOGDIR))) - { - /* - * Try updating the permissions of the containing log directory, using - * the log file permissions as a basis... - */ - - int log_dir_perm = 0300 | LogFilePerm; - /* LogFilePerm + owner write/search */ - if (log_dir_perm & 0040) - log_dir_perm |= 0010; /* Add group search */ - if (log_dir_perm & 0004) - log_dir_perm |= 0001; /* Add other search */ - - cupsdCheckPermissions(CUPS_LOGDIR, NULL, log_dir_perm, RunUser, Group, - 1, -1); - - *lf = cupsFileOpen(filename, "a"); - } - - if (*lf == NULL) - { - syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename, - strerror(errno)); - - if (FatalErrors & CUPSD_FATAL_LOG) - cupsdEndProcess(getpid(), 0); - - return (0); - } - } - - if (strncmp(filename, "/dev/", 5)) - { - /* - * Change ownership and permissions of non-device logs... - */ - - fchown(cupsFileNumber(*lf), RunUser, Group); - fchmod(cupsFileNumber(*lf), LogFilePerm); - } - } - - /* - * Do we need to rotate the log? - */ - - if (strncmp(logname, "/dev/", 5) && cupsFileTell(*lf) > MaxLogSize && - MaxLogSize > 0) - { - /* - * Rotate log file... - */ - - cupsFileClose(*lf); - - strcpy(backname, filename); - strlcat(backname, ".O", sizeof(backname)); - - unlink(backname); - rename(filename, backname); - - if ((*lf = cupsFileOpen(filename, "a")) == NULL) - { - syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename, - strerror(errno)); - - if (FatalErrors & CUPSD_FATAL_LOG) - cupsdEndProcess(getpid(), 0); - - return (0); - } - - /* - * Change ownership and permissions of non-device logs... - */ - - fchown(cupsFileNumber(*lf), RunUser, Group); - fchmod(cupsFileNumber(*lf), LogFilePerm); - } - - return (1); -} - - -/* * 'format_log_line()' - Format a line for a log file. * * This function resizes a global string buffer as needed. Each call returns diff --git a/scheduler/main.c b/scheduler/main.c index 411c65210..4f4eef8bb 100644 --- a/scheduler/main.c +++ b/scheduler/main.c @@ -1492,9 +1492,6 @@ launchd_checkin(void) { size_t i, /* Looping var */ count; /* Number of listeners */ -# ifdef HAVE_SSL - int portnum; /* Port number */ -# endif /* HAVE_SSL */ launch_data_t ld_msg, /* Launch data message */ ld_resp, /* Launch data response */ ld_array, /* Launch data array */ @@ -1626,17 +1623,7 @@ launchd_checkin(void) lis->fd = fd; # ifdef HAVE_SSL - portnum = 0; - -# ifdef AF_INET6 - if (lis->address.addr.sa_family == AF_INET6) - portnum = ntohs(lis->address.ipv6.sin6_port); - else -# endif /* AF_INET6 */ - if (lis->address.addr.sa_family == AF_INET) - portnum = ntohs(lis->address.ipv4.sin_port); - - if (portnum == 443) + if (_httpAddrPort(&(lis->address)) == 443) lis->encryption = HTTP_ENCRYPT_ALWAYS; # endif /* HAVE_SSL */ } diff --git a/scheduler/mime.c b/scheduler/mime.c index 5e3377a34..d1a905aa8 100644 --- a/scheduler/mime.c +++ b/scheduler/mime.c @@ -3,7 +3,7 @@ * * MIME database file routines for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2006 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -14,24 +14,24 @@ * * Contents: * - * mimeDelete() - Delete (free) a MIME database. - * mimeDeleteFilter() - Delete a filter from the MIME database. - * mimeDeleteType() - Delete a type from the MIME database. - * mimeFirstFilter() - Get the first filter in the MIME database. - * mimeFirstType() - Get the first type in the MIME database. - * mimeLoad() - Create a new MIME database from disk. - * mimeMerge() - Merge a MIME database from disk with the current one. - * mimeNew() - Create a new, empty MIME database. - * mimeNextFilter() - Get the next filter in the MIME database. - * mimeNextType() - Get the next type in the MIME database. - * mimeNumFilters() - Get the number of filters in a MIME database. - * mimeNumTypes() - Get the number of types in a MIME database. - * add_fcache() - Add a filter to the filter cache. - * compare_fcache() - Compare two filter cache entries. - * delete_fcache() - Free all memory used by the filter cache. - * delete_rules() - Free all memory for the given rule tree. - * load_convs() - Load a xyz.convs file... - * load_types() - Load a xyz.types file... + * mimeDelete() - Delete (free) a MIME database. + * mimeDeleteFilter() - Delete a filter from the MIME database. + * mimeDeleteType() - Delete a type from the MIME database. + * mimeFirstFilter() - Get the first filter in the MIME database. + * mimeFirstType() - Get the first type in the MIME database. + * mimeLoad() - Create a new MIME database from disk. + * mimeMerge() - Merge a MIME database from disk with the current one. + * mimeNew() - Create a new, empty MIME database. + * mimeNextFilter() - Get the next filter in the MIME database. + * mimeNextType() - Get the next type in the MIME database. + * mimeNumFilters() - Get the number of filters in a MIME database. + * mimeNumTypes() - Get the number of types in a MIME database. + * mime_add_fcache() - Add a filter to the filter cache. + * mime_compare_fcache() - Compare two filter cache entries. + * mime_delete_fcache() - Free all memory used by the filter cache. + * mime_delete_rules() - Free all memory for the given rule tree. + * mime_load_convs() - Load a xyz.convs file... + * mime_load_types() - Load a xyz.types file... */ /* @@ -59,15 +59,15 @@ typedef struct _mime_fcache_s /**** Filter cache structure ****/ * Local functions... */ -static const char *add_fcache(cups_array_t *filtercache, const char *name, - const char *filterpath); -static int compare_fcache(_mime_fcache_t *a, _mime_fcache_t *b); -static void delete_fcache(cups_array_t *filtercache); -static void delete_rules(mime_magic_t *rules); -static void load_convs(mime_t *mime, const char *filename, - const char *filterpath, - cups_array_t *filtercache); -static void load_types(mime_t *mime, const char *filename); +static const char *mime_add_fcache(cups_array_t *filtercache, const char *name, + const char *filterpath); +static int mime_compare_fcache(_mime_fcache_t *a, _mime_fcache_t *b); +static void mime_delete_fcache(cups_array_t *filtercache); +static void mime_delete_rules(mime_magic_t *rules); +static void mime_load_convs(mime_t *mime, const char *filename, + const char *filterpath, + cups_array_t *filtercache); +static void mime_load_types(mime_t *mime, const char *filename); static mime_t *mime_new(void); @@ -82,6 +82,8 @@ mimeDelete(mime_t *mime) /* I - MIME database */ mime_filter_t *filter; /* Current filter */ + DEBUG_printf(("mimeDelete(mime=%p)", mime)); + if (!mime) return; @@ -122,9 +124,23 @@ void mimeDeleteFilter(mime_t *mime, /* I - MIME database */ mime_filter_t *filter) /* I - Filter */ { + DEBUG_printf(("mimeDeleteFilter(mime=%p, filter=%p(%s/%s->%s/%s, cost=%d, " + "maxsize=" CUPS_LLFMT "))", mime, filter, + filter ? filter->src->super : "???", + filter ? filter->src->type : "???", + filter ? filter->dst->super : "???", + filter ? filter->dst->super : "???", + filter ? filter->cost : -1, + filter ? CUPS_LLCAST filter->maxsize : CUPS_LLCAST -1)); + if (!mime || !filter) return; +#ifdef DEBUG + if (!cupsArrayFind(mime->filters, filter)) + DEBUG_puts("1mimeDeleteFilter: Filter not in MIME database."); +#endif /* DEBUG */ + cupsArrayRemove(mime->filters, filter); free(filter); @@ -135,6 +151,7 @@ mimeDeleteFilter(mime_t *mime, /* I - MIME database */ if (mime->srcs) { + DEBUG_puts("1mimeDeleteFilter: Deleting source lookup cache."); cupsArrayDelete(mime->srcs); mime->srcs = NULL; } @@ -149,12 +166,20 @@ void mimeDeleteType(mime_t *mime, /* I - MIME database */ mime_type_t *mt) /* I - Type */ { + DEBUG_printf(("mimeDeleteType(mime=%p, mt=%p(%s/%s))", mime, mt, + mt ? mt->super : "???", mt ? mt->type : "???")); + if (!mime || !mt) return; +#ifdef DEBUG + if (!cupsArrayFind(mime->types, mt)) + DEBUG_puts("1mimeDeleteFilter: Type not in MIME database."); +#endif /* DEBUG */ + cupsArrayRemove(mime->types, mt); - delete_rules(mt->rules); + mime_delete_rules(mt->rules); free(mt); } @@ -166,10 +191,21 @@ mimeDeleteType(mime_t *mime, /* I - MIME database */ mime_filter_t * /* O - Filter or NULL */ mimeFirstFilter(mime_t *mime) /* I - MIME database */ { + DEBUG_printf(("6mimeFirstFilter(mime=%p)", mime)); + if (!mime) + { + DEBUG_puts("7mimeFirstFilter: Returning NULL."); return (NULL); + } else - return ((mime_filter_t *)cupsArrayFirst(mime->filters)); + { + mime_filter_t *first = (mime_filter_t *)cupsArrayFirst(mime->filters); + /* First filter */ + + DEBUG_printf(("7mimeFirstFilter: Returning %p.", first)); + return (first); + } } @@ -180,10 +216,21 @@ mimeFirstFilter(mime_t *mime) /* I - MIME database */ mime_type_t * /* O - Type or NULL */ mimeFirstType(mime_t *mime) /* I - MIME database */ { + DEBUG_printf(("6mimeFirstType(mime=%p)", mime)); + if (!mime) + { + DEBUG_puts("7mimeFirstType: Returning NULL."); return (NULL); + } else - return ((mime_type_t *)cupsArrayFirst(mime->types)); + { + mime_type_t *first = (mime_type_t *)cupsArrayFirst(mime->types); + /* First type */ + + DEBUG_printf(("7mimeFirstType: Returning %p.", first)); + return (first); + } } @@ -198,7 +245,15 @@ mime_t * /* O - New MIME database */ mimeLoad(const char *pathname, /* I - Directory to load */ const char *filterpath) /* I - Directory to load */ { - return (mimeLoadFilters(mimeLoadTypes(NULL, pathname), pathname, filterpath)); + mime_t *mime; /* New MIME database */ + + DEBUG_printf(("mimeLoad(pathname=\"%s\", filterpath=\"%s\")", pathname, + filterpath)); + + mime = mimeLoadFilters(mimeLoadTypes(NULL, pathname), pathname, filterpath); + DEBUG_printf(("1mimeLoad: Returning %p.", mime)); + + return (mime); } @@ -220,25 +275,35 @@ mimeLoadFilters(mime_t *mime, /* I - MIME database */ cups_array_t *filtercache; /* Filter cache */ + DEBUG_printf(("mimeLoadFilters(mime=%p, pathname=\"%s\", filterpath=\"%s\")", + mime, pathname, filterpath)); + /* * Range check input... */ if (!mime || !pathname || !filterpath) + { + DEBUG_puts("1mimeLoadFilters: Bad arguments."); return (mime); + } /* * Then open the directory specified by pathname... */ if ((dir = cupsDirOpen(pathname)) == NULL) + { + DEBUG_printf(("1mimeLoadFilters: Unable to open \"%s\": %s", pathname, + strerror(errno))); return (mime); + } /* * Read all the .convs files... */ - filtercache = cupsArrayNew((cups_array_func_t)compare_fcache, NULL); + filtercache = cupsArrayNew((cups_array_func_t)mime_compare_fcache, NULL); while ((dent = cupsDirRead(dir)) != NULL) { @@ -250,11 +315,12 @@ mimeLoadFilters(mime_t *mime, /* I - MIME database */ */ snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->filename); - load_convs(mime, filename, filterpath, filtercache); + DEBUG_printf(("1mimeLoadFilters: Loading \"%s\".", filename)); + mime_load_convs(mime, filename, filterpath, filtercache); } } - delete_fcache(filtercache); + mime_delete_fcache(filtercache); cupsDirClose(dir); @@ -278,12 +344,19 @@ mimeLoadTypes(mime_t *mime, /* I - MIME database or @code NULL@ to create a char filename[1024]; /* Full filename of .types file */ + DEBUG_printf(("mimeLoadTypes(mime=%p, pathname=\"%s\")", mime, pathname)); + /* * First open the directory specified by pathname... */ if ((dir = cupsDirOpen(pathname)) == NULL) + { + DEBUG_printf(("1mimeLoadTypes: Unable to open \"%s\": %s", pathname, + strerror(errno))); + DEBUG_printf(("1mimeLoadTypes: Returning %p.", mime)); return (mime); + } /* * If "mime" is NULL, make a new, empty database... @@ -295,6 +368,7 @@ mimeLoadTypes(mime_t *mime, /* I - MIME database or @code NULL@ to create a if (!mime) { cupsDirClose(dir); + DEBUG_puts("1mimeLoadTypes: Returning NULL."); return (NULL); } @@ -312,12 +386,15 @@ mimeLoadTypes(mime_t *mime, /* I - MIME database or @code NULL@ to create a */ snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->filename); - load_types(mime, filename); + DEBUG_printf(("1mimeLoadTypes: Loading \"%s\".", filename)); + mime_load_types(mime, filename); } } cupsDirClose(dir); + DEBUG_printf(("1mimeLoadTypes: Returning %p.", mime)); + return (mime); } @@ -329,10 +406,21 @@ mimeLoadTypes(mime_t *mime, /* I - MIME database or @code NULL@ to create a mime_filter_t * /* O - Filter or NULL */ mimeNextFilter(mime_t *mime) /* I - MIME database */ { + DEBUG_printf(("6mimeNextFilter(mime=%p)", mime)); + if (!mime) + { + DEBUG_puts("7mimeNextFilter: Returning NULL."); return (NULL); + } else - return ((mime_filter_t *)cupsArrayNext(mime->filters)); + { + mime_filter_t *next = (mime_filter_t *)cupsArrayNext(mime->filters); + /* Next filter */ + + DEBUG_printf(("7mimeNextFilter: Returning %p.", next)); + return (next); + } } @@ -343,10 +431,21 @@ mimeNextFilter(mime_t *mime) /* I - MIME database */ mime_type_t * /* O - Type or NULL */ mimeNextType(mime_t *mime) /* I - MIME database */ { + DEBUG_printf(("6mimeNextType(mime=%p)", mime)); + if (!mime) + { + DEBUG_puts("7mimeNextType: Returning NULL."); return (NULL); + } else - return ((mime_type_t *)cupsArrayNext(mime->types)); + { + mime_type_t *next = (mime_type_t *)cupsArrayNext(mime->types); + /* Next type */ + + DEBUG_printf(("7mimeNextType: Returning %p.", next)); + return (next); + } } @@ -357,10 +456,19 @@ mimeNextType(mime_t *mime) /* I - MIME database */ int mimeNumFilters(mime_t *mime) /* I - MIME database */ { + DEBUG_printf(("mimeNumFilters(mime=%p)", mime)); + if (!mime) + { + DEBUG_puts("1mimeNumFilters: Returning 0."); return (0); + } else + { + DEBUG_printf(("1mimeNumFilters: Returning %d.", + cupsArrayCount(mime->filters))); return (cupsArrayCount(mime->filters)); + } } @@ -371,33 +479,52 @@ mimeNumFilters(mime_t *mime) /* I - MIME database */ int mimeNumTypes(mime_t *mime) /* I - MIME database */ { + DEBUG_printf(("mimeNumTypes(mime=%p)", mime)); + if (!mime) + { + DEBUG_puts("1mimeNumTypes: Returning 0."); return (0); + } else + { + DEBUG_printf(("1mimeNumTypes: Returning %d.", + cupsArrayCount(mime->types))); return (cupsArrayCount(mime->types)); + } } /* - * 'add_fcache()' - Add a filter to the filter cache. + * 'mime_add_fcache()' - Add a filter to the filter cache. */ static const char * /* O - Full path to filter or NULL */ -add_fcache(cups_array_t *filtercache, /* I - Filter cache */ - const char *name, /* I - Filter name */ - const char *filterpath) /* I - Filter path */ +mime_add_fcache( + cups_array_t *filtercache, /* I - Filter cache */ + const char *name, /* I - Filter name */ + const char *filterpath) /* I - Filter path */ { _mime_fcache_t key, /* Search key */ *temp; /* New filter cache */ char path[1024]; /* Full path to filter */ + DEBUG_printf(("2mime_add_fcache(filtercache=%p, name=\"%s\", " + "filterpath=\"%s\")", filtercache, name, filterpath)); + key.name = (char *)name; if ((temp = (_mime_fcache_t *)cupsArrayFind(filtercache, &key)) != NULL) + { + DEBUG_printf(("3mime_add_fcache: Returning \"%s\".", temp->path)); return (temp->path); + } if ((temp = calloc(1, sizeof(_mime_fcache_t))) == NULL) + { + DEBUG_puts("3mime_add_fcache: Returning NULL."); return (NULL); + } temp->name = strdup(name); @@ -406,16 +533,17 @@ add_fcache(cups_array_t *filtercache, /* I - Filter cache */ cupsArrayAdd(filtercache, temp); + DEBUG_printf(("3mime_add_fcache: Returning \"%s\".", temp->path)); return (temp->path); } /* - * 'compare_fcache()' - Compare two filter cache entries. + * 'mime_compare_fcache()' - Compare two filter cache entries. */ static int /* O - Result of comparison */ -compare_fcache(_mime_fcache_t *a, /* I - First entry */ +mime_compare_fcache(_mime_fcache_t *a, /* I - First entry */ _mime_fcache_t *b) /* I - Second entry */ { return (strcmp(a->name, b->name)); @@ -423,15 +551,18 @@ compare_fcache(_mime_fcache_t *a, /* I - First entry */ /* - * 'delete_fcache()' - Free all memory used by the filter cache. + * 'mime_delete_fcache()' - Free all memory used by the filter cache. */ static void -delete_fcache(cups_array_t *filtercache)/* I - Filter cache */ +mime_delete_fcache( + cups_array_t *filtercache) /* I - Filter cache */ { _mime_fcache_t *current; /* Current cache entry */ + DEBUG_printf(("2mime_delete_fcache(filtercache=%p)", filtercache)); + for (current = (_mime_fcache_t *)cupsArrayFirst(filtercache); current; current = (_mime_fcache_t *)cupsArrayNext(filtercache)) @@ -449,15 +580,17 @@ delete_fcache(cups_array_t *filtercache)/* I - Filter cache */ /* - * 'delete_rules()' - Free all memory for the given rule tree. + * 'mime_delete_rules()' - Free all memory for the given rule tree. */ static void -delete_rules(mime_magic_t *rules) /* I - Rules to free */ +mime_delete_rules(mime_magic_t *rules) /* I - Rules to free */ { mime_magic_t *next; /* Next rule to free */ + DEBUG_printf(("2mime_delete_rules(rules=%p)", rules)); + /* * Free the rules list, descending recursively to free any child rules. */ @@ -467,7 +600,7 @@ delete_rules(mime_magic_t *rules) /* I - Rules to free */ next = rules->next; if (rules->child != NULL) - delete_rules(rules->child); + mime_delete_rules(rules->child); free(rules); rules = next; @@ -476,14 +609,15 @@ delete_rules(mime_magic_t *rules) /* I - Rules to free */ /* - * 'load_convs()' - Load a xyz.convs file... + * 'mime_load_convs()' - Load a xyz.convs file... */ static void -load_convs(mime_t *mime, /* I - MIME database */ - const char *filename, /* I - Convs file to load */ - const char *filterpath, /* I - Path for filters */ - cups_array_t *filtercache) /* I - Filter program cache */ +mime_load_convs( + mime_t *mime, /* I - MIME database */ + const char *filename, /* I - Convs file to load */ + const char *filterpath, /* I - Path for filters */ + cups_array_t *filtercache) /* I - Filter program cache */ { cups_file_t *fp; /* Convs file */ char line[1024], /* Input line from file */ @@ -497,16 +631,19 @@ load_convs(mime_t *mime, /* I - MIME database */ int cost; /* Cost of filter */ - DEBUG_printf(("load_convs(mime=%p, filename=\"%s\", filterpath=\"%s\", " - "filtercache=%p)\n", mime, filename, filterpath, filtercache)); - + DEBUG_printf(("2mime_load_convs(mime=%p, filename=\"%s\", filterpath=\"%s\", " + "filtercache=%p)", mime, filename, filterpath, filtercache)); /* * First try to open the file... */ if ((fp = cupsFileOpen(filename, "r")) == NULL) + { + DEBUG_printf(("3mime_load_convs: Unable to open \"%s\": %s", filename, + strerror(errno))); return; + } /* * Then read each line from the file, skipping any comments in the file... @@ -567,7 +704,7 @@ load_convs(mime_t *mime, /* I - MIME database */ if ((dsttype = mimeType(mime, super, type)) == NULL) { - DEBUG_printf(("load_convs: Destination type %s/%s not found!\n", + DEBUG_printf(("3mime_load_convs: Destination type %s/%s not found.", super, type)); continue; } @@ -600,9 +737,9 @@ load_convs(mime_t *mime, /* I - MIME database */ * Verify that the filter exists and is executable... */ - if (!add_fcache(filtercache, filter, filterpath)) + if (!mime_add_fcache(filtercache, filter, filterpath)) { - DEBUG_printf(("load_convs: Filter %s not found in %s!\n", filter, + DEBUG_printf(("mime_load_convs: Filter %s not found in %s.", filter, filterpath)); continue; } @@ -661,12 +798,12 @@ load_convs(mime_t *mime, /* I - MIME database */ /* - * 'load_types()' - Load a xyz.types file... + * 'mime_load_types()' - Load a xyz.types file... */ static void -load_types(mime_t *mime, /* I - MIME database */ - const char *filename) /* I - Types file to load */ +mime_load_types(mime_t *mime, /* I - MIME database */ + const char *filename) /* I - Types file to load */ { cups_file_t *fp; /* Types file */ int linelen; /* Length of line */ @@ -678,14 +815,18 @@ load_types(mime_t *mime, /* I - MIME database */ mime_type_t *typeptr; /* New MIME type */ - DEBUG_printf(("load_types(mime=%p, filename=\"%s\")\n", mime, filename)); + DEBUG_printf(("2mime_load_types(mime=%p, filename=\"%s\")", mime, filename)); /* * First try to open the file... */ if ((fp = cupsFileOpen(filename, "r")) == NULL) + { + DEBUG_printf(("3mime_load_types: Unable to open \"%s\": %s", filename, + strerror(errno))); return; + } /* * Then read each line from the file, skipping any comments in the file... diff --git a/scheduler/network.c b/scheduler/network.c index 7f30b1e25..9048ad599 100644 --- a/scheduler/network.c +++ b/scheduler/network.c @@ -264,12 +264,7 @@ cupsdNetIFUpdate(void) if (match) { - if (lis->address.addr.sa_family == AF_INET) - temp->port = ntohs(lis->address.ipv4.sin_port); -#ifdef AF_INET6 - else if (lis->address.addr.sa_family == AF_INET6) - temp->port = ntohs(lis->address.ipv6.sin6_port); -#endif /* AF_INET6 */ + temp->port = _httpAddrPort(&(lis->address)); break; } } diff --git a/scheduler/org.cups.cupsd.plist b/scheduler/org.cups.cupsd.plist index 97c4208e1..ccc861d8f 100644 --- a/scheduler/org.cups.cupsd.plist +++ b/scheduler/org.cups.cupsd.plist @@ -21,6 +21,17 @@ <string>/usr/sbin/cupsd</string> <string>-l</string> </array> + <!-- These environment variables are only used when CUPS is compiled + with --enable-debug-printfs --> + <key>EnvironmentVariables</key> + <dict> + <key>CUPS_DEBUG_LOG</key> + <string>/var/log/cups/debug_log</string> + <key>CUPS_DEBUG_LEVEL</key> + <string>3</string> + <key>CUPS_DEBUG_FILTER</key> + <string>^(http|_http|ipp|_ipp|mime).*</string> + </dict> <key>ServiceIPC</key> <true/> <key>Sockets</key> diff --git a/scheduler/printers.c b/scheduler/printers.c index de4b637de..e3c7ad394 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -1409,8 +1409,11 @@ cupsdRenamePrinter( mimeDeleteType(MimeDatabase, p->filetype); p->filetype = mimeAddType(MimeDatabase, "printer", name); - mimeDeleteType(MimeDatabase, p->prefiltertype); - p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", name); + if (p->prefiltertype) + { + mimeDeleteType(MimeDatabase, p->prefiltertype); + p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", name); + } /* * Rename the printer... @@ -2447,7 +2450,8 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ if (p->pc && p->pc->prefilters) { - p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", p->name); + if (!p->prefiltertype) + p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", p->name); for (filter = (char *)cupsArrayFirst(p->pc->prefilters); filter; @@ -3563,9 +3567,8 @@ add_printer_filter( size_t maxsize = 0; /* Maximum supported file size */ mime_type_t *temptype, /* MIME type looping var */ *desttype; /* Destination MIME type */ - char filename[1024], /* Full filter filename */ - *dirsep; /* Pointer to directory separator */ - struct stat fileinfo; /* File information */ + mime_filter_t *filterptr; /* MIME filter */ + char filename[1024]; /* Full filter filename */ cupsdLogMessage(CUPSD_LOG_DEBUG2, @@ -3633,85 +3636,24 @@ add_printer_filter( } /* - * See if the filter program exists; if not, stop the printer and flag - * the error! + * Check permissions on the filter and its containing directory... */ if (strcmp(program, "-")) { + _cups_fc_result_t result; /* Result of file check */ + if (program[0] == '/') strlcpy(filename, program, sizeof(filename)); else snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin, program); - if (stat(filename, &fileinfo)) - { - memset(&fileinfo, 0, sizeof(fileinfo)); + result = _cupsFileCheck(filename, _CUPS_FILE_CHECK_PROGRAM, !RunUser, + cupsdLogFCMessage, p); - snprintf(p->state_message, sizeof(p->state_message), - "Printer driver \"%s\" not available: %s", filename, - strerror(errno)); - cupsdSetPrinterReasons(p, "+cups-missing-filter-warning"); - - cupsdLogMessage(CUPSD_LOG_ERROR, "%s: %s", p->name, p->state_message); - } - - /* - * When running as root, do additional security checks... - */ - - else if (!RunUser) - { - /* - * Only use filters that are owned by root and do not have world write - * permissions. - */ - - if (fileinfo.st_uid || - (fileinfo.st_gid && (fileinfo.st_mode & S_IWGRP)) || - (fileinfo.st_mode & (S_ISUID | S_IWOTH)) != 0) - { - snprintf(p->state_message, sizeof(p->state_message), - "Printer driver \"%s\" has insecure permissions " - "(0%o/uid=%d/gid=%d).", filename, fileinfo.st_mode, - (int)fileinfo.st_uid, (int)fileinfo.st_gid); - -#ifdef __APPLE__ /* Don't flag filters with group write for "admin" */ - if (fileinfo.st_uid || - (fileinfo.st_gid && fileinfo.st_gid != 80 && - (fileinfo.st_mode & S_IWGRP)) || - (fileinfo.st_mode & (S_ISUID | S_IWOTH))) -#endif /* __APPLE__ */ - cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning"); - - cupsdLogMessage(CUPSD_LOG_WARN, "%s: %s", p->name, p->state_message); - } - else if (fileinfo.st_mode) - { - /* - * Similarly, check that the parent directory is also owned by root and - * does not have world write permissions. - */ - - if ((dirsep = strrchr(filename, '/')) != NULL) - *dirsep = '\0'; - - if (!stat(filename, &fileinfo) && - (fileinfo.st_uid || - (fileinfo.st_gid && (fileinfo.st_mode & S_IWGRP)) || - (fileinfo.st_mode & (S_ISUID | S_IWOTH)) != 0)) - { - snprintf(p->state_message, sizeof(p->state_message), - "Printer driver directory \"%s\" has insecure permissions " - "(0%o/uid=%d/gid=%d).", filename, fileinfo.st_mode, - (int)fileinfo.st_uid, (int)fileinfo.st_gid); - - cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning"); - - cupsdLogMessage(CUPSD_LOG_WARN, "%s: %s", p->name, p->state_message); - } - } - } + if (result == _CUPS_FILE_CHECK_MISSING || + result == _CUPS_FILE_CHECK_WRONG_TYPE) + return; } /* @@ -3732,7 +3674,8 @@ add_printer_filter( "%s", p->name, temptype->super, temptype->type, desttype->super, desttype->type, cost, program); - mimeAddFilter(MimeDatabase, temptype, desttype, cost, program); + filterptr = mimeAddFilter(MimeDatabase, temptype, desttype, cost, + program); if (!mimeFilterLookup(MimeDatabase, desttype, filtertype)) { @@ -3750,8 +3693,12 @@ add_printer_filter( "%s", p->name, temptype->super, temptype->type, filtertype->super, filtertype->type, cost, program); - mimeAddFilter(MimeDatabase, temptype, filtertype, cost, program); + filterptr = mimeAddFilter(MimeDatabase, temptype, filtertype, cost, + program); } + + if (filterptr) + filterptr->maxsize = maxsize; } } @@ -4060,7 +4007,7 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ ppd_info.st_mtime = 1; ippDelete(p->ppd_attrs); - p->ppd_attrs = ippNew(); + p->ppd_attrs = NULL; _ppdCacheDestroy(p->pc); p->pc = NULL; @@ -4094,6 +4041,8 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ finishings[0] = IPP_FINISHINGS_NONE; num_finishings = 1; + p->ppd_attrs = ippNew(); + if ((ppd = ppdOpenFile(ppd_name)) != NULL) { /* @@ -4899,7 +4848,9 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ */ if ((ppd_attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL)) != NULL && - ppd_attr->value) + ppd_attr->value && + !_cupsFileCheck(ppd_attr->value, _CUPS_FILE_CHECK_FILE, !RunUser, + cupsdLogFCMessage, p)) { CGImageRef imageRef = NULL;/* Current icon image */ CGImageRef biggestIconRef = NULL; diff --git a/scheduler/process.c b/scheduler/process.c index 80c3fcb59..8b3e3f23b 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -317,7 +317,6 @@ cupsdStartProcess( char *real_argv[103], /* Real command-line arguments */ cups_exec[1024]; /* Path to "cups-exec" program */ int user; /* Command UID */ - struct stat commandinfo; /* Command file information */ cupsd_proc_t *proc; /* New process record */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* POSIX signal handler */ @@ -329,6 +328,8 @@ cupsdStartProcess( #endif /* __APPLE__ */ + *pid = 0; + /* * Figure out the UID for the child process... */ @@ -344,110 +345,9 @@ cupsdStartProcess( * Check the permissions of the command we are running... */ - if (stat(command, &commandinfo)) - { - *pid = 0; - - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStartProcess(command=\"%s\", argv=%p, envp=%p, " - "infd=%d, outfd=%d, errfd=%d, backfd=%d, sidefd=%d, root=%d, " - "profile=%p, job=%p(%d), pid=%p) = %d", - command, argv, envp, infd, outfd, errfd, backfd, sidefd, - root, profile, job, job ? job->id : 0, pid, *pid); - cupsdLogMessage(CUPSD_LOG_ERROR, - "%s%s \"%s\" not available: %s", - job && job->printer ? job->printer->name : "", - job && job->printer ? ": Printer driver" : "Program", - command, strerror(errno)); - - if (job && job->printer) - { - if (cupsdSetPrinterReasons(job->printer, "+cups-missing-filter-warning")) - cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL, - "Printer driver \"%s\" not available.", command); - } - - return (0); - } - else if (!RunUser && - ((commandinfo.st_mode & (S_ISUID | S_IWOTH)) || - commandinfo.st_uid)) - { - *pid = 0; - - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStartProcess(command=\"%s\", argv=%p, envp=%p, " - "infd=%d, outfd=%d, errfd=%d, backfd=%d, sidefd=%d, root=%d, " - "profile=%p, job=%p(%d), pid=%p) = %d", - command, argv, envp, infd, outfd, errfd, backfd, sidefd, - root, profile, job, job ? job->id : 0, pid, *pid); - cupsdLogMessage(CUPSD_LOG_ERROR, - "%s%s \"%s\" has insecure permissions " - "(0%o/uid=%d/gid=%d).", - job && job->printer ? job->printer->name : "", - job && job->printer ? ": Printer driver" : "Program", - command, commandinfo.st_mode, - (int)commandinfo.st_uid, (int)commandinfo.st_gid); - - if (job && job->printer) - { - if (cupsdSetPrinterReasons(job->printer, "+cups-insecure-filter-warning")) - cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL, - "Printer driver \"%s\" has insecure permissions " - "(0%o/uid=%d/gid=%d).", command, commandinfo.st_mode, - (int)commandinfo.st_uid, (int)commandinfo.st_gid); - } - - errno = EPERM; - - return (0); - } - else if ((commandinfo.st_uid != user || !(commandinfo.st_mode & S_IXUSR)) && - (commandinfo.st_gid != Group || !(commandinfo.st_mode & S_IXGRP)) && - !(commandinfo.st_mode & S_IXOTH)) - { - *pid = 0; - - cupsdLogMessage(CUPSD_LOG_DEBUG2, - "cupsdStartProcess(command=\"%s\", argv=%p, envp=%p, " - "infd=%d, outfd=%d, errfd=%d, backfd=%d, sidefd=%d, root=%d, " - "profile=%p, job=%p(%d), pid=%p) = %d", - command, argv, envp, infd, outfd, errfd, backfd, sidefd, - root, profile, job, job ? job->id : 0, pid, *pid); - cupsdLogMessage(CUPSD_LOG_ERROR, - "%s%s \"%s\" does not have execute permissions " - "(0%o/uid=%d/gid=%d).", - job && job->printer ? job->printer->name : "", - job && job->printer ? ": Printer driver" : "Program", - command, commandinfo.st_mode, (int)commandinfo.st_uid, - (int)commandinfo.st_gid); - - errno = EPERM; + if (_cupsFileCheck(command, _CUPS_FILE_CHECK_PROGRAM, !RunUser, + cupsdLogFCMessage, job ? job->printer : NULL)) return (0); - } - else if (!RunUser && commandinfo.st_gid && (commandinfo.st_mode & S_IWGRP)) - { - cupsdLogMessage(CUPSD_LOG_WARN, - "%s%s \"%s\" has insecure permissions " - "(0%o/uid=%d/gid=%d).", - job && job->printer ? job->printer->name : "", - job && job->printer ? ": Printer driver" : "Program", - command, commandinfo.st_mode, - (int)commandinfo.st_uid, (int)commandinfo.st_gid); - -#ifdef __APPLE__ /* Don't flag filters with group write for "admin" */ - if (commandinfo.st_gid != 80 && job && job->printer) -#else - if (job && job->printer) -#endif /* __APPLE__ */ - { - if (cupsdSetPrinterReasons(job->printer, "+cups-insecure-filter-warning")) - cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL, - "Printer driver \"%s\" has insecure permissions " - "(0%o/uid=%d/gid=%d).", command, commandinfo.st_mode, - (int)commandinfo.st_uid, (int)commandinfo.st_gid); - } - } #if defined(__APPLE__) if (envp) diff --git a/scheduler/testdirsvc.c b/scheduler/testdirsvc.c index cf607e20b..bf3030428 100644 --- a/scheduler/testdirsvc.c +++ b/scheduler/testdirsvc.c @@ -3,7 +3,7 @@ * * Browsing test program for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -297,7 +297,7 @@ main(int argc, /* I - Number of command-line arguments */ * Sleep for any remaining time... */ - if (seconds > 0) + if (seconds > 0) sleep(seconds); } diff --git a/scheduler/testmime.c b/scheduler/testmime.c index 1a8713801..1561e81b7 100644 --- a/scheduler/testmime.c +++ b/scheduler/testmime.c @@ -14,9 +14,11 @@ * * Contents: * - * main() - Main entry for the test program. - * print_rules() - Print the rules for a file type... - * type_dir() - Show the MIME types for a given directory. + * main() - Main entry for the test program. + * add_ppd_filter() - Add a printer filter from a PPD. + * add_ppd_filters() - Add all filters from a PPD. + * print_rules() - Print the rules for a file type... + * type_dir() - Show the MIME types for a given directory. */ /* @@ -25,6 +27,8 @@ #include <cups/string-private.h> #include <cups/dir.h> +#include <cups/debug-private.h> +#include <cups/ppd-private.h> #include "mime.h" @@ -32,6 +36,9 @@ * Local functions... */ +static void add_ppd_filter(mime_t *mime, mime_type_t *filtertype, + const char *filter); +static void add_ppd_filters(mime_t *mime, ppd_file_t *ppd); static void print_rules(mime_magic_t *rules); static void type_dir(mime_t *mime, const char *dirname); @@ -53,6 +60,8 @@ main(int argc, /* I - Number of command-line args */ mime_t *mime; /* MIME database */ mime_type_t *src, /* Source type */ *dst; /* Destination type */ + struct stat srcinfo; /* Source information */ + ppd_file_t *ppd; /* PPD file */ cups_array_t *filters; /* Filters for the file */ mime_filter_t *filter; /* Current filter */ @@ -60,7 +69,10 @@ main(int argc, /* I - Number of command-line args */ mime = NULL; src = NULL; dst = NULL; - filter_path = "../filter:../pdftops:" CUPS_SERVERBIN "/filter"; + ppd = NULL; + filter_path = "../filter:" CUPS_SERVERBIN "/filter"; + + srcinfo.st_size = 0; for (i = 1; i < argc; i ++) if (!strcmp(argv[i], "-d")) @@ -68,7 +80,12 @@ main(int argc, /* I - Number of command-line args */ i ++; if (i < argc) + { mime = mimeLoad(argv[i], filter_path); + + if (ppd) + add_ppd_filters(mime, ppd); + } } else if (!strcmp(argv[i], "-f")) { @@ -77,12 +94,28 @@ main(int argc, /* I - Number of command-line args */ if (i < argc) filter_path = argv[i]; } + else if (!strcmp(argv[i], "-p")) + { + i ++; + + if (i < argc) + { + ppd = ppdOpenFile(argv[i]); + + if (mime) + add_ppd_filters(mime, ppd); + } + } else if (!src) { if (!mime) mime = mimeLoad("../conf", filter_path); + if (ppd) + add_ppd_filters(mime, ppd); + src = mimeFileType(mime, argv[i], NULL, &compression); + stat(argv[i], &srcinfo); if (src) printf("%s: %s/%s%s\n", argv[i], src->super, src->type, @@ -102,7 +135,7 @@ main(int argc, /* I - Number of command-line args */ sscanf(argv[i], "%15[^/]/%31s", super, type); dst = mimeType(mime, super, type); - filters = mimeFilter(mime, src, dst, &cost); + filters = mimeFilter2(mime, src, srcinfo.st_size, dst, &cost); if (!filters) { @@ -111,15 +144,25 @@ main(int argc, /* I - Number of command-line args */ } else { - printf("Filter cost = %d\n", cost); + int first = 1; /* First filter shown? */ - filter = (mime_filter_t *)cupsArrayFirst(filters); - fputs(filter->filter, stdout); + printf("Filter cost = %d\n", cost); - for (filter = (mime_filter_t *)cupsArrayNext(filters); + for (filter = (mime_filter_t *)cupsArrayFirst(filters); filter; filter = (mime_filter_t *)cupsArrayNext(filters)) - printf(" | %s", filter->filter); + { + if (!strcmp(filter->filter, "-")) + continue; + + if (first) + { + first = 0; + fputs(filter->filter, stdout); + } + else + printf(" | %s", filter->filter); + } putchar('\n'); @@ -128,7 +171,11 @@ main(int argc, /* I - Number of command-line args */ } if (!mime) + { mime = mimeLoad("../conf", filter_path); + if (ppd) + add_ppd_filters(mime, ppd); + } if (!src) { @@ -150,7 +197,6 @@ main(int argc, /* I - Number of command-line args */ filter->filter, filter->cost); type_dir(mime, "../doc"); - type_dir(mime, "../man"); } return (0); @@ -158,6 +204,167 @@ main(int argc, /* I - Number of command-line args */ /* + * 'add_printer_filter()' - Add a printer filter from a PPD. + */ + +static void +add_ppd_filter(mime_t *mime, /* I - MIME database */ + mime_type_t *filtertype, /* I - Filter or prefilter MIME type */ + const char *filter) /* I - Filter to add */ +{ + char super[MIME_MAX_SUPER], /* Super-type for filter */ + type[MIME_MAX_TYPE], /* Type for filter */ + dsuper[MIME_MAX_SUPER], /* Destination super-type for filter */ + dtype[MIME_MAX_TYPE], /* Destination type for filter */ + dest[MIME_MAX_SUPER + MIME_MAX_TYPE + 2], + /* Destination super/type */ + program[1024]; /* Program/filter name */ + int cost; /* Cost of filter */ + size_t maxsize = 0; /* Maximum supported file size */ + mime_type_t *temptype, /* MIME type looping var */ + *desttype; /* Destination MIME type */ + mime_filter_t *filterptr; /* MIME filter */ + + + DEBUG_printf(("add_ppd_filter(mime=%p, filtertype=%p(%s/%s), filter=\"%s\")", + mime, filtertype, filtertype->super, filtertype->type, filter)); + + /* + * Parse the filter string; it should be in one of the following formats: + * + * source/type cost program + * source/type cost maxsize(nnnn) program + * source/type dest/type cost program + * source/type dest/type cost maxsize(nnnn) program + */ + + if (sscanf(filter, "%15[^/]/%255s%*[ \t]%15[^/]/%255s%d%*[ \t]%1023[^\n]", + super, type, dsuper, dtype, &cost, program) == 6) + { + snprintf(dest, sizeof(dest), "test/%s/%s", dsuper, dtype); + + if ((desttype = mimeType(mime, "printer", dest)) == NULL) + desttype = mimeAddType(mime, "printer", dest); + } + else + { + if (sscanf(filter, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, &cost, + program) == 4) + { + desttype = filtertype; + } + else + { + printf("testmime: Invalid filter string \"%s\".\n", filter); + return; + } + } + + if (!strncmp(program, "maxsize(", 8)) + { + char *ptr; /* Pointer into maxsize(nnnn) program */ + + maxsize = strtoll(program + 8, &ptr, 10); + + if (*ptr != ')') + { + printf("testmime: Invalid filter string \"%s\".\n", filter); + return; + } + + ptr ++; + while (_cups_isspace(*ptr)) + ptr ++; + + _cups_strcpy(program, ptr); + } + + /* + * Add the filter to the MIME database, supporting wildcards as needed... + */ + + for (temptype = mimeFirstType(mime); + temptype; + temptype = mimeNextType(mime)) + if (((super[0] == '*' && strcasecmp(temptype->super, "printer")) || + !strcasecmp(temptype->super, super)) && + (type[0] == '*' || !strcasecmp(temptype->type, type))) + { + if (desttype != filtertype) + { + DEBUG_printf(("add_ppd_filter: Adding filter %s/%s %s/%s %d %s", + temptype->super, temptype->type, desttype->super, + desttype->type, cost, program)); + filterptr = mimeAddFilter(mime, temptype, desttype, cost, program); + + if (!mimeFilterLookup(mime, desttype, filtertype)) + { + DEBUG_printf(("add_printer_filter: Adding filter %s/%s %s/%s 0 -", + desttype->super, desttype->type, filtertype->super, + filtertype->type)); + mimeAddFilter(mime, desttype, filtertype, cost, "-"); + } + } + else + { + DEBUG_printf(("add_printer_filter: Adding filter %s/%s %s/%s %d %s", + temptype->super, temptype->type, filtertype->super, + filtertype->type, cost, program)); + filterptr = mimeAddFilter(mime, temptype, filtertype, cost, program); + } + + if (filterptr) + filterptr->maxsize = maxsize; + } +} + + +/* + * 'add_ppd_filters()' - Add all filters from a PPD. + */ + +static void +add_ppd_filters(mime_t *mime, /* I - MIME database */ + ppd_file_t *ppd) /* I - PPD file */ +{ + _ppd_cache_t *pc; /* Cache data for PPD */ + const char *value; /* Filter definition value */ + mime_type_t *filter, /* Filter type */ + *prefilter; /* Pre-filter type */ + + + pc = _ppdCacheCreateWithPPD(ppd); + if (!pc) + return; + + filter = mimeAddType(mime, "printer", "test"); + + if (pc->filters) + { + for (value = (const char *)cupsArrayFirst(pc->filters); + value; + value = (const char *)cupsArrayNext(pc->filters)) + add_ppd_filter(mime, filter, value); + } + else + { + add_ppd_filter(mime, filter, "application/vnd.cups-raw 0 -"); + add_ppd_filter(mime, filter, "application/vnd.cups-postscript 0 -"); + } + + if (pc->prefilters) + { + prefilter = mimeAddType(mime, "prefilter", "test"); + + for (value = (const char *)cupsArrayFirst(pc->prefilters); + value; + value = (const char *)cupsArrayNext(pc->prefilters)) + add_ppd_filter(mime, prefilter, value); + } +} + + +/* * 'print_rules()' - Print the rules for a file type... */ diff --git a/scheduler/type.c b/scheduler/type.c index 6f4706e20..78652b529 100644 --- a/scheduler/type.c +++ b/scheduler/type.c @@ -3,7 +3,7 @@ * * MIME typing routines for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2006 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -14,13 +14,13 @@ * * Contents: * - * mimeAddType() - Add a MIME type to a database. - * mimeAddTypeRule() - Add a detection rule for a file type. - * mimeFileType() - Determine the type of a file. - * mimeType() - Lookup a file type. - * compare_types() - Compare two MIME super/type names. - * checkrules() - Check each rule in a list. - * patmatch() - Pattern matching... + * mimeAddType() - Add a MIME type to a database. + * mimeAddTypeRule() - Add a detection rule for a file type. + * mimeFileType() - Determine the type of a file. + * mimeType() - Lookup a file type. + * mime_compare_types() - Compare two MIME super/type names. + * mime_check_rules() - Check each rule in a list. + * mime_patmatch() - Pattern matching. */ /* @@ -50,10 +50,10 @@ typedef struct _mime_filebuf_s /**** File buffer for MIME typing ****/ * Local functions... */ -static int compare_types(mime_type_t *t0, mime_type_t *t1); -static int checkrules(const char *filename, _mime_filebuf_t *fb, - mime_magic_t *rules); -static int patmatch(const char *s, const char *pat); +static int mime_compare_types(mime_type_t *t0, mime_type_t *t1); +static int mime_check_rules(const char *filename, _mime_filebuf_t *fb, + mime_magic_t *rules); +static int mime_patmatch(const char *s, const char *pat); /* @@ -90,42 +90,60 @@ mimeAddType(mime_t *mime, /* I - MIME database */ const char *type) /* I - Type name */ { mime_type_t *temp; /* New MIME type */ + size_t typelen; /* Length of type name */ + DEBUG_printf(("mimeAddType(mime=%p, super=\"%s\", type=\"%s\")", mime, super, + type)); + /* * Range check input... */ if (!mime || !super || !type) + { + DEBUG_puts("1mimeAddType: Returning NULL (bad arguments)."); return (NULL); + } /* * See if the type already exists; if so, return the existing type... */ if ((temp = mimeType(mime, super, type)) != NULL) + { + DEBUG_printf(("1mimeAddType: Returning %p (existing).", temp)); return (temp); + } /* * The type doesn't exist; add it... */ if (!mime->types) - mime->types = cupsArrayNew((cups_array_func_t)compare_types, NULL); + mime->types = cupsArrayNew((cups_array_func_t)mime_compare_types, NULL); if (!mime->types) + { + DEBUG_puts("1mimeAddType: Returning NULL (no types)."); return (NULL); + } + + typelen = strlen(type) + 1; - if ((temp = calloc(1, sizeof(mime_type_t) - MIME_MAX_TYPE + - strlen(type) + 1)) == NULL) + if ((temp = calloc(1, sizeof(mime_type_t) - MIME_MAX_TYPE + typelen)) == NULL) + { + DEBUG_puts("1mimeAddType: Returning NULL (out of memory)."); return (NULL); + } strlcpy(temp->super, super, sizeof(temp->super)); - strcpy(temp->type, type); /* Safe: temp->type is allocated */ + memcpy(temp->type, type, typelen); temp->priority = 100; cupsArrayAdd(mime->types, temp); + DEBUG_printf(("1mimeAddType: Returning %p (new).", temp)); return (temp); } @@ -151,6 +169,9 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */ *current; /* Current rule */ + DEBUG_printf(("mimeAddTypeRule(mt=%p(%s/%s), rule=\"%s\")", mt, + mt ? mt->super : "???", mt ? mt->type : "???", rule)); + /* * Range check input... */ @@ -177,8 +198,6 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */ logic = MIME_MAGIC_NOP; invert = 0; - DEBUG_printf(("mimeAddTypeRule: %s/%s: %s", mt->super, mt->type, rule)); - while (*rule != '\0') { while (isspace(*rule & 255)) @@ -186,13 +205,13 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */ if (*rule == '(') { - DEBUG_puts("mimeAddTypeRule: New parenthesis group"); + DEBUG_puts("1mimeAddTypeRule: New parenthesis group"); logic = MIME_MAGIC_NOP; rule ++; } else if (*rule == ')') { - DEBUG_puts("mimeAddTypeRule: Close paren..."); + DEBUG_puts("1mimeAddTypeRule: Close paren..."); if (current == NULL || current->parent == NULL) return (-1); @@ -227,11 +246,11 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */ current->prev = NULL; current->parent = temp; - DEBUG_printf(("mimeAddTypeRule: Creating new AND group %p...", temp)); + DEBUG_printf(("1mimeAddTypeRule: Creating new AND group %p.", temp)); } else if (current->parent) { - DEBUG_printf(("mimeAddTypeRule: Setting group %p op to AND...", + DEBUG_printf(("1mimeAddTypeRule: Setting group %p op to AND.", current->parent)); current->parent->op = MIME_MAGIC_AND; } @@ -258,8 +277,8 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */ if ((temp = calloc(1, sizeof(mime_magic_t))) == NULL) return (-1); - DEBUG_printf(("mimeAddTypeRule: Creating new AND group %p inside OR " - "group", temp)); + DEBUG_printf(("1mimeAddTypeRule: Creating new AND group %p inside OR " + "group.", temp)); while (current->prev != NULL) { @@ -279,7 +298,7 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */ * This isn't the top rule, so go up one level... */ - DEBUG_puts("mimeAddTypeRule: Going up one level"); + DEBUG_puts("1mimeAddTypeRule: Going up one level."); current = current->parent; } } @@ -289,7 +308,7 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */ } else if (*rule == '!') { - DEBUG_puts("mimeAddTypeRule: NOT"); + DEBUG_puts("1mimeAddTypeRule: NOT"); invert = 1; rule ++; } @@ -463,8 +482,8 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */ * Add parenthetical grouping... */ - DEBUG_printf(("mimeAddTypeRule: Making new OR group %p for " - "parenthesis...", temp)); + DEBUG_printf(("1mimeAddTypeRule: Making new OR group %p for " + "parenthesis.", temp)); temp->op = MIME_MAGIC_OR; @@ -479,9 +498,9 @@ mimeAddTypeRule(mime_type_t *mt, /* I - Type to add to */ logic = MIME_MAGIC_OR; } - DEBUG_printf(("mimeAddTypeRule: adding %p: %s, op=MIME_MAGIC_%s(%d), " - "logic=MIME_MAGIC_%s, invert=%d", temp, name, debug_ops[op], - op, debug_ops[logic], invert)); + DEBUG_printf(("1mimeAddTypeRule: Adding %p: %s, op=MIME_MAGIC_%s(%d), " + "logic=MIME_MAGIC_%s, invert=%d.", temp, name, + debug_ops[op], op, debug_ops[logic], invert)); /* * Fill in data for the rule... @@ -579,14 +598,22 @@ mimeFileType(mime_t *mime, /* I - MIME database */ */ if (!mime || !pathname) + { + DEBUG_puts("1mimeFileType: Returning NULL."); return (NULL); + } /* * Try to open the file... */ if ((fb.fp = cupsFileOpen(pathname, "r")) == NULL) + { + DEBUG_printf(("1mimeFileType: Unable to open \"%s\": %s", pathname, + strerror(errno))); + DEBUG_puts("1mimeFileType: Returning NULL."); return (NULL); + } fb.offset = -1; fb.length = 0; @@ -614,7 +641,7 @@ mimeFileType(mime_t *mime, /* I - MIME database */ for (type = (mime_type_t *)cupsArrayFirst(mime->types), best = NULL; type; type = (mime_type_t *)cupsArrayNext(mime->types)) - if (checkrules(base, &fb, type->rules)) + if (mime_check_rules(base, &fb, type->rules)) { if (!best || type->priority > best->priority) best = type; @@ -625,10 +652,15 @@ mimeFileType(mime_t *mime, /* I - MIME database */ */ if (compression) + { *compression = cupsFileCompression(fb.fp); + DEBUG_printf(("1mimeFileType: *compression=%d", *compression)); + } cupsFileClose(fb.fp); + DEBUG_printf(("1mimeFileType: Returning %p(%s/%s).", best, + best ? best->super : "???", best ? best->type : "???")); return (best); } @@ -642,15 +674,22 @@ mimeType(mime_t *mime, /* I - MIME database */ const char *super, /* I - Super-type name */ const char *type) /* I - Type name */ { - mime_type_t key; /* MIME type search key*/ + mime_type_t key, /* MIME type search key */ + *mt; /* Matching type */ + + DEBUG_printf(("mimeType(mime=%p, super=\"%s\", type=\"%s\")", mime, super, + type)); /* * Range check input... */ if (!mime || !super || !type) + { + DEBUG_puts("1mimeType: Returning NULL."); return (NULL); + } /* * Lookup the type in the array... @@ -659,17 +698,19 @@ mimeType(mime_t *mime, /* I - MIME database */ strlcpy(key.super, super, sizeof(key.super)); strlcpy(key.type, type, sizeof(key.type)); - return ((mime_type_t *)cupsArrayFind(mime->types, &key)); + mt = (mime_type_t *)cupsArrayFind(mime->types, &key); + DEBUG_printf(("1mimeType: Returning %p.", mt)); + return (mt); } /* - * 'compare_types()' - Compare two MIME super/type names. + * 'mime_compare_types()' - Compare two MIME super/type names. */ static int /* O - Result of comparison */ -compare_types(mime_type_t *t0, /* I - First type */ - mime_type_t *t1) /* I - Second type */ +mime_compare_types(mime_type_t *t0, /* I - First type */ + mime_type_t *t1) /* I - Second type */ { int i; /* Result of comparison */ @@ -682,13 +723,14 @@ compare_types(mime_type_t *t0, /* I - First type */ /* - * 'checkrules()' - Check each rule in a list. + * 'mime_check_rules()' - Check each rule in a list. */ static int /* O - 1 if match, 0 if no match */ -checkrules(const char *filename, /* I - Filename */ - _mime_filebuf_t *fb, /* I - File to check */ - mime_magic_t *rules) /* I - Rules to check */ +mime_check_rules( + const char *filename, /* I - Filename */ + _mime_filebuf_t *fb, /* I - File to check */ + mime_magic_t *rules) /* I - Rules to check */ { int n; /* Looping var */ int region; /* Region to look at */ @@ -699,7 +741,7 @@ checkrules(const char *filename, /* I - Filename */ unsigned char *bufptr; /* Pointer into buffer */ - DEBUG_printf(("checkrules(filename=\"%s\", fb=%p, rules=%p)", filename, + DEBUG_printf(("4mime_check_rules(filename=\"%s\", fb=%p, rules=%p)", filename, fb, rules)); if (rules == NULL) @@ -721,7 +763,7 @@ checkrules(const char *filename, /* I - Filename */ switch (rules->op) { case MIME_MAGIC_MATCH : - result = patmatch(filename, rules->value.matchv); + result = mime_patmatch(filename, rules->value.matchv); break; case MIME_MAGIC_ASCII : @@ -811,7 +853,7 @@ checkrules(const char *filename, /* I - Filename */ break; case MIME_MAGIC_STRING : - DEBUG_printf(("checkrules: string(%d, \"%s\")", rules->offset, + DEBUG_printf(("5mime_check_rules: string(%d, \"%s\")", rules->offset, rules->value.stringv)); /* @@ -830,8 +872,8 @@ checkrules(const char *filename, /* I - Filename */ sizeof(fb->buffer)); fb->offset = rules->offset; - DEBUG_printf(("checkrules: loaded %d byte fb->buffer at %d, starts " - "with \"%c%c%c%c\"...", + DEBUG_printf(("5mime_check_rules: loaded %d byte fb->buffer at %d, starts " + "with \"%c%c%c%c\".", fb->length, fb->offset, fb->buffer[0], fb->buffer[1], fb->buffer[2], fb->buffer[3])); } @@ -846,7 +888,7 @@ checkrules(const char *filename, /* I - Filename */ else result = (memcmp(fb->buffer + rules->offset - fb->offset, rules->value.stringv, rules->length) == 0); - DEBUG_printf(("checkrules: result=%d", result)); + DEBUG_printf(("5mime_check_rules: result=%d", result)); break; case MIME_MAGIC_ISTRING : @@ -1028,7 +1070,7 @@ checkrules(const char *filename, /* I - Filename */ default : if (rules->child != NULL) - result = checkrules(filename, fb, rules->child); + result = mime_check_rules(filename, fb, rules->child); else result = 0; break; @@ -1047,7 +1089,7 @@ checkrules(const char *filename, /* I - Filename */ * the the rule set is false... */ - DEBUG_printf(("checkrules: result of test %p (MIME_MAGIC_%s) is %d", + DEBUG_printf(("5mime_check_rules: result of test %p (MIME_MAGIC_%s) is %d", rules, debug_ops[rules->op], result)); if ((result && logic == MIME_MAGIC_OR) || @@ -1066,12 +1108,12 @@ checkrules(const char *filename, /* I - Filename */ /* - * 'patmatch()' - Pattern matching... + * 'mime_patmatch()' - Pattern matching. */ -static int /* O - 1 if match, 0 if no match */ -patmatch(const char *s, /* I - String to match against */ - const char *pat) /* I - Pattern to match against */ +static int /* O - 1 if match, 0 if no match */ +mime_patmatch(const char *s, /* I - String to match against */ + const char *pat) /* I - Pattern to match against */ { /* * Range check the input... @@ -1103,7 +1145,7 @@ patmatch(const char *s, /* I - String to match against */ while (*s != '\0') { - if (patmatch(s, pat)) + if (mime_patmatch(s, pat)) return (1); s ++; diff --git a/scheduler/util.c b/scheduler/util.c index b170f8052..e686b6f8b 100644 --- a/scheduler/util.c +++ b/scheduler/util.c @@ -3,7 +3,7 @@ * * Mini-daemon utility functions for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2005 by Easy Software Products. * * These coded instructions, statements, and computer programs are the diff --git a/scheduler/util.h b/scheduler/util.h index ecf7645a4..b98476555 100644 --- a/scheduler/util.h +++ b/scheduler/util.h @@ -3,7 +3,7 @@ * * Mini-daemon utility definitions for CUPS. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2011 by Apple Inc. * Copyright 1997-2005 by Easy Software Products. * * These coded instructions, statements, and computer programs are the |