summaryrefslogtreecommitdiff
path: root/scheduler
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2011-04-22 23:02:56 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2011-04-22 23:02:56 +0000
commit22c9029b44a790ba1ee894027431dcea1ec2aeab (patch)
tree20e787f4b9f7c9c574cf3450bf8326c83192fe39 /scheduler
parent07ed0e9a4385437b52e7195b681e600c2f1c5623 (diff)
downloadcups-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.c91
-rw-r--r--scheduler/conf.c39
-rw-r--r--scheduler/conf.h6
-rw-r--r--scheduler/cups-deviced.c6
-rw-r--r--scheduler/cups-driverd.cxx60
-rw-r--r--scheduler/cups-exec.c20
-rw-r--r--scheduler/cups-polld.c2
-rw-r--r--scheduler/cupsd.h1
-rw-r--r--scheduler/dirsvc.c12
-rw-r--r--scheduler/filter.c170
-rw-r--r--scheduler/ipp.c14
-rw-r--r--scheduler/job.c96
-rw-r--r--scheduler/listen.c13
-rw-r--r--scheduler/log.c410
-rw-r--r--scheduler/main.c15
-rw-r--r--scheduler/mime.c269
-rw-r--r--scheduler/network.c7
-rw-r--r--scheduler/org.cups.cupsd.plist11
-rw-r--r--scheduler/printers.c109
-rw-r--r--scheduler/process.c108
-rw-r--r--scheduler/testdirsvc.c4
-rw-r--r--scheduler/testmime.c229
-rw-r--r--scheduler/type.c150
-rw-r--r--scheduler/util.c2
-rw-r--r--scheduler/util.h2
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