diff options
Diffstat (limited to 'scheduler')
-rw-r--r-- | scheduler/auth.c | 35 | ||||
-rw-r--r-- | scheduler/cert.c | 32 | ||||
-rw-r--r-- | scheduler/cert.h | 13 | ||||
-rw-r--r-- | scheduler/client.c | 86 | ||||
-rw-r--r-- | scheduler/colorman.c | 8 | ||||
-rw-r--r-- | scheduler/conf.c | 860 | ||||
-rw-r--r-- | scheduler/conf.h | 8 | ||||
-rw-r--r-- | scheduler/cupsd.h | 11 | ||||
-rw-r--r-- | scheduler/cupsfilter.c | 13 | ||||
-rw-r--r-- | scheduler/dirsvc.c | 36 | ||||
-rw-r--r-- | scheduler/ipp.c | 233 | ||||
-rw-r--r-- | scheduler/job.c | 45 | ||||
-rw-r--r-- | scheduler/log.c | 39 | ||||
-rw-r--r-- | scheduler/main.c | 108 | ||||
-rw-r--r-- | scheduler/printers.c | 48 | ||||
-rw-r--r-- | scheduler/testmime.c | 8 |
16 files changed, 1006 insertions, 577 deletions
diff --git a/scheduler/auth.c b/scheduler/auth.c index 5791c025..a82a605e 100644 --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -1,5 +1,5 @@ /* - * "$Id: auth.c 10376 2012-03-22 20:53:47Z mike $" + * "$Id: auth.c 10776 2012-12-17 22:17:08Z mike $" * * Authorization routines for the CUPS scheduler. * @@ -89,14 +89,13 @@ extern const char *cssmErrorString(int error); typedef struct xucred cupsd_ucred_t; # define CUPSD_UCRED_UID(c) (c).cr_uid #else +# ifndef __OpenBSD__ typedef struct ucred cupsd_ucred_t; +# else +typedef struct sockpeercred cupsd_ucred_t; +# endif # define CUPSD_UCRED_UID(c) (c).uid #endif /* HAVE_SYS_UCRED_H */ -#ifdef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID -/* Not in public headers... */ -extern void krb5_ipc_client_set_target_uid(uid_t); -extern void krb5_ipc_client_clear_target(void); -#endif /* HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */ /* @@ -593,15 +592,7 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ while (isspace(*authorization & 255)) authorization ++; - if ((localuser = cupsdFindCert(authorization)) != NULL) - { - strlcpy(username, localuser->username, sizeof(username)); - - cupsdLogMessage(CUPSD_LOG_DEBUG, - "[Client %d] Authorized as %s using Local", con->http.fd, - username); - } - else + if ((localuser = cupsdFindCert(authorization)) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, "[Client %d] Local authentication certificate not found.", @@ -609,12 +600,12 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ return; } -#ifdef HAVE_GSSAPI - if (localuser->ccache) - con->type = CUPSD_AUTH_NEGOTIATE; - else -#endif /* HAVE_GSSAPI */ - con->type = CUPSD_AUTH_BASIC; + strlcpy(username, localuser->username, sizeof(username)); + con->type = localuser->type; + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "[Client %d] Authorized as %s using Local", con->http.fd, + username); } else if (!strncmp(authorization, "Basic", 5)) { @@ -2597,5 +2588,5 @@ to64(char *s, /* O - Output string */ /* - * End of "$Id: auth.c 10376 2012-03-22 20:53:47Z mike $". + * End of "$Id: auth.c 10776 2012-12-17 22:17:08Z mike $". */ diff --git a/scheduler/cert.c b/scheduler/cert.c index 1937d35f..5e0f06e1 100644 --- a/scheduler/cert.c +++ b/scheduler/cert.c @@ -1,9 +1,9 @@ /* - * "$Id: cert.c 10257 2012-02-12 04:34:46Z mike $" + * "$Id: cert.c 10776 2012-12-17 22:17:08Z mike $" * * Authentication certificate routines for the CUPS scheduler. * - * Copyright 2007-2011 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 1997-2006 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -42,7 +42,7 @@ void cupsdAddCert(int pid, /* I - Process ID */ const char *username, /* I - Username */ - void *ccache) /* I - Kerberos credentials or NULL */ + int type) /* I - AuthType for username */ { int i; /* Looping var */ cupsd_cert_t *cert; /* Current certificate */ @@ -66,7 +66,8 @@ cupsdAddCert(int pid, /* I - Process ID */ * Fill in the certificate information... */ - cert->pid = pid; + cert->pid = pid; + cert->type = type; strlcpy(cert->username, username, sizeof(cert->username)); for (i = 0; i < 32; i ++) @@ -260,16 +261,6 @@ cupsdAddCert(int pid, /* I - Process ID */ close(fd); /* - * Add Kerberos credentials as needed... - */ - -#ifdef HAVE_GSSAPI - cert->ccache = (krb5_ccache)ccache; -#else - (void)ccache; -#endif /* HAVE_GSSAPI */ - - /* * Insert the certificate at the front of the list... */ @@ -308,15 +299,6 @@ cupsdDeleteCert(int pid) /* I - Process ID */ else prev->next = cert->next; -#ifdef HAVE_GSSAPI - /* - * Release Kerberos credentials as needed... - */ - - if (cert->ccache) - krb5_cc_destroy(KerberosContext, cert->ccache); -#endif /* HAVE_GSSAPI */ - free(cert); /* @@ -449,10 +431,10 @@ cupsdInitCerts(void) */ if (!RunUser) - cupsdAddCert(0, "root", NULL); + cupsdAddCert(0, "root", cupsdDefaultAuthType()); } /* - * End of "$Id: cert.c 10257 2012-02-12 04:34:46Z mike $". + * End of "$Id: cert.c 10776 2012-12-17 22:17:08Z mike $". */ diff --git a/scheduler/cert.h b/scheduler/cert.h index e456a1ad..fbec27c8 100644 --- a/scheduler/cert.h +++ b/scheduler/cert.h @@ -1,9 +1,9 @@ /* - * "$Id: cert.h 9350 2010-11-04 23:23:25Z mike $" + * "$Id: cert.h 10776 2012-12-17 22:17:08Z mike $" * * Authentication certificate definitions for the CUPS scheduler. * - * Copyright 2007-2010 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 1997-2005 by Easy Software Products. * * These coded instructions, statements, and computer programs are the @@ -23,9 +23,7 @@ typedef struct cupsd_cert_s int pid; /* Process ID (0 for root certificate) */ char certificate[33]; /* 32 hex characters, or 128 bits */ char username[33]; /* Authenticated username */ -#ifdef HAVE_GSSAPI - krb5_ccache ccache; /* Kerberos credential cache */ -#endif /* HAVE_GSSAPI */ + int type; /* AuthType for username */ } cupsd_cert_t; @@ -43,8 +41,7 @@ VAR time_t RootCertTime /* Root certificate update time */ * Prototypes... */ -extern void cupsdAddCert(int pid, const char *username, - void *ccache); +extern void cupsdAddCert(int pid, const char *username, int type); extern void cupsdDeleteCert(int pid); extern void cupsdDeleteAllCerts(void); extern cupsd_cert_t *cupsdFindCert(const char *certificate); @@ -52,5 +49,5 @@ extern void cupsdInitCerts(void); /* - * End of "$Id: cert.h 9350 2010-11-04 23:23:25Z mike $". + * End of "$Id: cert.h 10776 2012-12-17 22:17:08Z mike $". */ diff --git a/scheduler/client.c b/scheduler/client.c index 4d42bcea..75ed7578 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -1,5 +1,5 @@ /* - * "$Id: client.c 10455 2012-05-07 22:41:30Z mike $" + * "$Id: client.c 10834 2013-01-21 15:29:47Z mike $" * * Client routines for the CUPS scheduler. * @@ -32,7 +32,7 @@ * compare_clients() - Compare two client connections. * data_ready() - Check whether data is available from a client. * get_file() - Get a filename and state info. - * install_conf_file() - Install a configuration file. + * install_cupsd_conf() - Install a configuration file. * is_cgi() - Is the resource a CGI script/program? * is_path_absolute() - Is a path absolute and free of relative elements * (i.e. ".."). @@ -95,7 +95,7 @@ static int compare_clients(cupsd_client_t *a, cupsd_client_t *b, static int data_ready(cupsd_client_t *con); static char *get_file(cupsd_client_t *con, struct stat *filestats, char *filename, int len); -static http_status_t install_conf_file(cupsd_client_t *con); +static http_status_t install_cupsd_conf(cupsd_client_t *con); static int is_cgi(cupsd_client_t *con, const char *filename, struct stat *filestats, mime_type_t *type); static int is_path_absolute(const char *path); @@ -1271,7 +1271,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ switch (con->http.state) { case HTTP_GET_SEND : - if (!strncmp(con->uri, "/printers/", 10) && + if ((!strncmp(con->uri, "/ppd/", 5) || + !strncmp(con->uri, "/printers/", 10)) && !strcmp(con->uri + strlen(con->uri) - 4, ".ppd")) { /* @@ -1281,8 +1282,15 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ con->uri[strlen(con->uri) - 4] = '\0'; /* Drop ".ppd" */ - if ((p = cupsdFindPrinter(con->uri + 10)) != NULL) + if (!strncmp(con->uri, "/ppd/", 5)) + p = cupsdFindPrinter(con->uri + 5); + else + p = cupsdFindPrinter(con->uri + 10); + + if (p) + { snprintf(con->uri, sizeof(con->uri), "/ppd/%s.ppd", p->name); + } else { if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE)) @@ -1294,7 +1302,8 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ break; } } - else if ((!strncmp(con->uri, "/printers/", 10) || + else if ((!strncmp(con->uri, "/icons/", 7) || + !strncmp(con->uri, "/printers/", 10) || !strncmp(con->uri, "/classes/", 9)) && !strcmp(con->uri + strlen(con->uri) - 4, ".png")) { @@ -1305,7 +1314,9 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ con->uri[strlen(con->uri) - 4] = '\0'; /* Drop ".png" */ - if (!strncmp(con->uri, "/printers/", 10)) + if (!strncmp(con->uri, "/icons/", 7)) + p = cupsdFindPrinter(con->uri + 7); + else if (!strncmp(con->uri, "/printers/", 10)) p = cupsdFindPrinter(con->uri + 10); else p = cupsdFindClass(con->uri + 9); @@ -1666,17 +1677,14 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ * Validate the resource name... */ - if (strncmp(con->uri, "/admin/conf/", 12) || - strchr(con->uri + 12, '/') || - strlen(con->uri) == 12) + if (strcmp(con->uri, "/admin/conf/cupsd.conf")) { /* - * PUT can only be done to configuration files under - * /admin/conf... + * PUT can only be done to the cupsd.conf file... */ cupsdLogMessage(CUPSD_LOG_ERROR, - "[Client %d] Request for subdirectory \"%s\".", + "[Client %d] Disallowed PUT request for \"%s\".", con->http.fd, con->uri); if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE)) @@ -2044,7 +2052,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */ * Install the configuration file... */ - status = install_conf_file(con); + status = install_cupsd_conf(con); /* * Return the status to the client... @@ -2573,14 +2581,7 @@ cupsdSendHeader( con->http.hostname); #ifdef HAVE_GSSAPI else if (auth_type == CUPSD_AUTH_NEGOTIATE) - { -# ifdef AF_LOCAL - if (_httpAddrFamily(con->http.hostaddr) == AF_LOCAL) - strlcpy(auth_str, "Basic realm=\"CUPS\"", sizeof(auth_str)); - else -# endif /* AF_LOCAL */ strlcpy(auth_str, "Negotiate", sizeof(auth_str)); - } #endif /* HAVE_GSSAPI */ if (con->best && auth_type != CUPSD_AUTH_NEGOTIATE && @@ -3301,14 +3302,13 @@ get_file(cupsd_client_t *con, /* I - Client connection */ /* - * 'install_conf_file()' - Install a configuration file. + * 'install_cupsd_conf()' - Install a configuration file. */ static http_status_t /* O - Status */ -install_conf_file(cupsd_client_t *con) /* I - Connection */ +install_cupsd_conf(cupsd_client_t *con) /* I - Connection */ { char filename[1024]; /* Configuration filename */ - mode_t mode; /* Permissions */ cups_file_t *in, /* Input file */ *out; /* Output file */ char buffer[16384]; /* Copy buffer */ @@ -3330,19 +3330,14 @@ install_conf_file(cupsd_client_t *con) /* I - Connection */ * Open the new config file... */ - snprintf(filename, sizeof(filename), "%s%s", ServerRoot, con->uri + 11); - if (!strcmp(con->uri, "/admin/conf/printers.conf")) - mode = ConfigFilePerm & 0600; - else - mode = ConfigFilePerm; - - if ((out = cupsdCreateConfFile(filename, mode)) == NULL) + if ((out = cupsdCreateConfFile(ConfigurationFile, ConfigFilePerm)) == NULL) { cupsFileClose(in); return (HTTP_SERVER_ERROR); } - cupsdLogMessage(CUPSD_LOG_INFO, "Installing config file \"%s\"...", filename); + cupsdLogMessage(CUPSD_LOG_INFO, "Installing config file \"%s\"...", + ConfigurationFile); /* * Copy from the request to the new config file... @@ -3353,12 +3348,12 @@ install_conf_file(cupsd_client_t *con) /* I - Connection */ { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to copy to config file \"%s\": %s", - filename, strerror(errno)); + ConfigurationFile, strerror(errno)); cupsFileClose(in); cupsFileClose(out); - snprintf(filename, sizeof(filename), "%s%s.N", ServerRoot, con->uri + 11); + snprintf(filename, sizeof(filename), "%s.N", ConfigurationFile); cupsdRemoveFile(filename); return (HTTP_SERVER_ERROR); @@ -3370,7 +3365,7 @@ install_conf_file(cupsd_client_t *con) /* I - Connection */ cupsFileClose(in); - if (cupsdCloseCreatedConfFile(out, filename)) + if (cupsdCloseCreatedConfFile(out, ConfigurationFile)) return (HTTP_SERVER_ERROR); /* @@ -3381,14 +3376,10 @@ install_conf_file(cupsd_client_t *con) /* I - Connection */ cupsdClearString(&con->filename); /* - * If the cupsd.conf file was updated, set the NeedReload flag... + * Set the NeedReload flag... */ - if (!strcmp(con->uri, "/admin/conf/cupsd.conf")) - NeedReload = RELOAD_CUPSD; - else - NeedReload = RELOAD_ALL; - + NeedReload = RELOAD_CUPSD; ReloadTime = time(NULL); /* @@ -3621,7 +3612,6 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */ server_name[1024], /* SERVER_NAME environment variable */ server_port[1024]; /* SERVER_PORT environment variable */ ipp_attribute_t *attr; /* attributes-natural-language attribute */ - void *ccache = NULL; /* Kerberos credentials */ /* @@ -3973,7 +3963,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */ */ if (con->username[0]) - cupsdAddCert(pid, con->username, ccache); + cupsdAddCert(pid, con->username, con->type); cupsdLogMessage(CUPSD_LOG_DEBUG, "[CGI] Started %s (PID %d)", command, pid); @@ -4021,7 +4011,7 @@ valid_host(cupsd_client_t *con) /* I - Client connection */ !strncmp(host, "[::1]:", 6)); } -#ifdef HAVE_DNSSD +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) /* * Check if the hostname is something.local (Bonjour); if so, allow it. */ @@ -4040,7 +4030,7 @@ valid_host(cupsd_client_t *con) /* I - Client connection */ !_cups_strcasecmp(end, ".local.") || !_cups_strncasecmp(end, ".local.:", 8))) return (1); -#endif /* HAVE_DNSSD */ +#endif /* HAVE_DNSSD || HAVE_AVAHI */ /* * Check if the hostname is an IP address... @@ -4101,7 +4091,7 @@ valid_host(cupsd_client_t *con) /* I - Client connection */ } } -#ifdef HAVE_DNSSD +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) for (a = (cupsd_alias_t *)cupsArrayFirst(DNSSDAlias); a; a = (cupsd_alias_t *)cupsArrayNext(DNSSDAlias)) @@ -4126,7 +4116,7 @@ valid_host(cupsd_client_t *con) /* I - Client connection */ return (1); } } -#endif /* HAVE_DNSSD */ +#endif /* HAVE_DNSSD || HAVE_AVAHI */ /* * Check for interface hostname matches... @@ -4228,5 +4218,5 @@ write_pipe(cupsd_client_t *con) /* I - Client connection */ /* - * End of "$Id: client.c 10455 2012-05-07 22:41:30Z mike $". + * End of "$Id: client.c 10834 2013-01-21 15:29:47Z mike $". */ diff --git a/scheduler/colorman.c b/scheduler/colorman.c index 061c505a..acbc1f97 100644 --- a/scheduler/colorman.c +++ b/scheduler/colorman.c @@ -1,5 +1,5 @@ /* - * "$Id: colorman.c 10514 2012-05-25 03:11:18Z mike $" + * "$Id: colorman.c 10869 2013-02-19 23:53:01Z mike $" * * Color management routines for the CUPS scheduler. * @@ -1128,14 +1128,14 @@ colord_delete_device( message = COLORD_DBUS_MSG(COLORD_DBUS_PATH, "DeleteDevice"); dbus_message_iter_init_append(message, &args); - dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &device_id); + dbus_message_iter_append_basic(&args, DBUS_TYPE_OBJECT_PATH, &device_path); /* * Send the DeleteDevice request synchronously... */ dbus_error_init(&error); - cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling DeleteDevice(%s)", device_id); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Calling DeleteDevice(%s)", device_path); reply = dbus_connection_send_with_reply_and_block(colord_con, message, COLORD_DBUS_TIMEOUT, &error); @@ -1505,5 +1505,5 @@ colord_unregister_printer( /* - * End of "$Id: colorman.c 10514 2012-05-25 03:11:18Z mike $". + * End of "$Id: colorman.c 10869 2013-02-19 23:53:01Z mike $". */ diff --git a/scheduler/conf.c b/scheduler/conf.c index aaf42734..e319a2ca 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -1,5 +1,5 @@ /* - * "$Id: conf.c 10482 2012-05-18 19:51:02Z mike $" + * "$Id: conf.c 10824 2013-01-18 19:58:41Z mike $" * * Configuration routines for the CUPS scheduler. * @@ -14,23 +14,25 @@ * * Contents: * - * cupsdAddAlias() - Add a host alias. + * cupsdAddAlias() - Add a host alias. * cupsdCheckPermissions() - Fix the mode and ownership of a file or - * directory. + * directory. * cupsdDefaultAuthType() - Get the default AuthType. * cupsdFreeAliases() - Free all of the alias entries. * cupsdReadConfiguration() - Read the cupsd.conf file. - * get_address() - Get an address + port number from a line. + * get_address() - Get an address + port number from a line. * get_addr_and_mask() - Get an IP address and netmask. - * mime_error_cb() - Log a MIME error. - * parse_aaa() - Parse authentication, authorization, and access - * control lines. + * mime_error_cb() - Log a MIME error. + * parse_aaa() - Parse authentication, authorization, and access + * control lines. * parse_fatal_errors() - Parse FatalErrors values in a string. - * parse_groups() - Parse system group names in a string. - * parse_protocols() - Parse browse protocols in a string. - * read_configuration() - Read a configuration file. - * read_location() - Read a <Location path> definition. - * read_policy() - Read a <Policy name> definition. + * parse_groups() - Parse system group names in a string. + * parse_protocols() - Parse browse protocols in a string. + * parse_variable() - Parse a variable line. + * read_cupsd_conf() - Read the cupsd.conf configuration file. + * read_cups_files_conf() - Read the cups-files.conf configuration file. + * read_location() - Read a <Location path> definition. + * read_policy() - Read a <Policy name> definition. * set_policy_defaults() - Set default policy values as needed. */ @@ -83,35 +85,25 @@ typedef struct * Local globals... */ -static int default_auth_type = CUPSD_AUTH_AUTO; - /* Default AuthType, if not specified */ -static const cupsd_var_t variables[] = +static const cupsd_var_t cupsd_vars[] = { - { "AccessLog", &AccessLog, CUPSD_VARTYPE_STRING }, { "AutoPurgeJobs", &JobAutoPurge, CUPSD_VARTYPE_BOOLEAN }, -#ifdef HAVE_DNSSD +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) { "BrowseDNSSDSubTypes", &DNSSDSubTypes, CUPSD_VARTYPE_STRING }, -#endif /* HAVE_DNSSD */ +#endif /* HAVE_DNSSD || HAVE_AVAHI */ { "BrowseWebIF", &BrowseWebIF, CUPSD_VARTYPE_BOOLEAN }, { "Browsing", &Browsing, CUPSD_VARTYPE_BOOLEAN }, - { "CacheDir", &CacheDir, CUPSD_VARTYPE_STRING }, { "Classification", &Classification, CUPSD_VARTYPE_STRING }, { "ClassifyOverride", &ClassifyOverride, CUPSD_VARTYPE_BOOLEAN }, - { "ConfigFilePerm", &ConfigFilePerm, CUPSD_VARTYPE_INTEGER }, - { "DataDir", &DataDir, CUPSD_VARTYPE_STRING }, { "DefaultLanguage", &DefaultLanguage, CUPSD_VARTYPE_STRING }, { "DefaultLeaseDuration", &DefaultLeaseDuration, CUPSD_VARTYPE_TIME }, { "DefaultPaperSize", &DefaultPaperSize, CUPSD_VARTYPE_STRING }, { "DefaultPolicy", &DefaultPolicy, CUPSD_VARTYPE_STRING }, { "DefaultShared", &DefaultShared, CUPSD_VARTYPE_BOOLEAN }, { "DirtyCleanInterval", &DirtyCleanInterval, CUPSD_VARTYPE_TIME }, - { "DocumentRoot", &DocumentRoot, CUPSD_VARTYPE_STRING }, - { "ErrorLog", &ErrorLog, CUPSD_VARTYPE_STRING }, { "ErrorPolicy", &ErrorPolicy, CUPSD_VARTYPE_STRING }, - { "FileDevice", &FileDevice, CUPSD_VARTYPE_BOOLEAN }, { "FilterLimit", &FilterLimit, CUPSD_VARTYPE_INTEGER }, { "FilterNice", &FilterNice, CUPSD_VARTYPE_INTEGER }, - { "FontPath", &FontPath, CUPSD_VARTYPE_STRING }, #ifdef HAVE_GSSAPI { "GSSServiceName", &GSSServiceName, CUPSD_VARTYPE_STRING }, #endif /* HAVE_GSSAPI */ @@ -126,8 +118,6 @@ static const cupsd_var_t variables[] = { "LimitRequestBody", &MaxRequestSize, CUPSD_VARTYPE_INTEGER }, { "ListenBackLog", &ListenBackLog, CUPSD_VARTYPE_INTEGER }, { "LogDebugHistory", &LogDebugHistory, CUPSD_VARTYPE_INTEGER }, - { "LogFilePerm", &LogFilePerm, CUPSD_VARTYPE_INTEGER }, - { "LPDConfigFile", &LPDConfigFile, CUPSD_VARTYPE_STRING }, { "MaxActiveJobs", &MaxActiveJobs, CUPSD_VARTYPE_INTEGER }, { "MaxClients", &MaxClients, CUPSD_VARTYPE_INTEGER }, { "MaxClientsPerHost", &MaxClientsPerHost, CUPSD_VARTYPE_INTEGER }, @@ -146,18 +136,34 @@ static const cupsd_var_t variables[] = { "MaxSubscriptionsPerPrinter",&MaxSubscriptionsPerPrinter, CUPSD_VARTYPE_INTEGER }, { "MaxSubscriptionsPerUser", &MaxSubscriptionsPerUser, CUPSD_VARTYPE_INTEGER }, { "MultipleOperationTimeout", &MultipleOperationTimeout, CUPSD_VARTYPE_TIME }, - { "PageLog", &PageLog, CUPSD_VARTYPE_STRING }, { "PageLogFormat", &PageLogFormat, CUPSD_VARTYPE_STRING }, { "PreserveJobFiles", &JobFiles, CUPSD_VARTYPE_TIME }, { "PreserveJobHistory", &JobHistory, CUPSD_VARTYPE_TIME }, - { "Printcap", &Printcap, CUPSD_VARTYPE_STRING }, - { "PrintcapGUI", &PrintcapGUI, CUPSD_VARTYPE_STRING }, { "ReloadTimeout", &ReloadTimeout, CUPSD_VARTYPE_TIME }, - { "RemoteRoot", &RemoteRoot, CUPSD_VARTYPE_STRING }, - { "RequestRoot", &RequestRoot, CUPSD_VARTYPE_STRING }, { "RIPCache", &RIPCache, CUPSD_VARTYPE_STRING }, { "RootCertDuration", &RootCertDuration, CUPSD_VARTYPE_TIME }, { "ServerAdmin", &ServerAdmin, CUPSD_VARTYPE_STRING }, + { "ServerName", &ServerName, CUPSD_VARTYPE_STRING }, + { "StrictConformance", &StrictConformance, CUPSD_VARTYPE_BOOLEAN }, + { "Timeout", &Timeout, CUPSD_VARTYPE_TIME }, + { "WebInterface", &WebInterface, CUPSD_VARTYPE_BOOLEAN } +}; +static const cupsd_var_t cupsfiles_vars[] = +{ + { "AccessLog", &AccessLog, CUPSD_VARTYPE_STRING }, + { "CacheDir", &CacheDir, CUPSD_VARTYPE_STRING }, + { "ConfigFilePerm", &ConfigFilePerm, CUPSD_VARTYPE_INTEGER }, + { "DataDir", &DataDir, CUPSD_VARTYPE_STRING }, + { "DocumentRoot", &DocumentRoot, CUPSD_VARTYPE_STRING }, + { "ErrorLog", &ErrorLog, CUPSD_VARTYPE_STRING }, + { "FileDevice", &FileDevice, CUPSD_VARTYPE_BOOLEAN }, + { "FontPath", &FontPath, CUPSD_VARTYPE_STRING }, + { "LogFilePerm", &LogFilePerm, CUPSD_VARTYPE_INTEGER }, + { "LPDConfigFile", &LPDConfigFile, CUPSD_VARTYPE_STRING }, + { "PageLog", &PageLog, CUPSD_VARTYPE_STRING }, + { "Printcap", &Printcap, CUPSD_VARTYPE_STRING }, + { "RemoteRoot", &RemoteRoot, CUPSD_VARTYPE_STRING }, + { "RequestRoot", &RequestRoot, CUPSD_VARTYPE_STRING }, { "ServerBin", &ServerBin, CUPSD_VARTYPE_PATHNAME }, #ifdef HAVE_SSL { "ServerCertificate", &ServerCertificate, CUPSD_VARTYPE_PATHNAME }, @@ -165,20 +171,17 @@ static const cupsd_var_t variables[] = { "ServerKey", &ServerKey, CUPSD_VARTYPE_PATHNAME }, # endif /* HAVE_LIBSSL || HAVE_GNUTLS */ #endif /* HAVE_SSL */ - { "ServerName", &ServerName, CUPSD_VARTYPE_STRING }, { "ServerRoot", &ServerRoot, CUPSD_VARTYPE_PATHNAME }, { "SMBConfigFile", &SMBConfigFile, CUPSD_VARTYPE_STRING }, { "StateDir", &StateDir, CUPSD_VARTYPE_STRING }, - { "StrictConformance", &StrictConformance, CUPSD_VARTYPE_BOOLEAN }, #ifdef HAVE_AUTHORIZATION_H { "SystemGroupAuthKey", &SystemGroupAuthKey, CUPSD_VARTYPE_STRING }, #endif /* HAVE_AUTHORIZATION_H */ - { "TempDir", &TempDir, CUPSD_VARTYPE_PATHNAME }, - { "Timeout", &Timeout, CUPSD_VARTYPE_TIME }, - { "WebInterface", &WebInterface, CUPSD_VARTYPE_BOOLEAN } + { "TempDir", &TempDir, CUPSD_VARTYPE_PATHNAME } }; -#define NUM_VARS (sizeof(variables) / sizeof(variables[0])) +static int default_auth_type = CUPSD_AUTH_AUTO; + /* Default AuthType, if not specified */ static const unsigned ones[4] = { @@ -203,7 +206,12 @@ static int parse_aaa(cupsd_location_t *loc, char *line, static int parse_fatal_errors(const char *s); static int parse_groups(const char *s); static int parse_protocols(const char *s); -static int read_configuration(cups_file_t *fp); +static int parse_variable(const char *filename, int linenum, + const char *line, const char *value, + size_t num_vars, + const cupsd_var_t *vars); +static int read_cupsd_conf(cups_file_t *fp); +static int read_cups_files_conf(cups_file_t *fp); static int read_location(cups_file_t *fp, char *name, int linenum); static int read_policy(cups_file_t *fp, char *name, int linenum); static void set_policy_defaults(cupsd_policy_t *pol); @@ -583,7 +591,7 @@ cupsdReadConfiguration(void) cupsdSetString(&PrintcapGUI, "/usr/bin/glpoptions"); cupsdSetString(&FontPath, CUPS_FONTPATH); cupsdSetString(&RemoteRoot, "remroot"); - cupsdSetStringf(&ServerHeader, "CUPS/%d.%d", CUPS_VERSION_MAJOR, + cupsdSetStringf(&ServerHeader, "CUPS/%d.%d IPP/2.1", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR); cupsdSetString(&StateDir, CUPS_STATEDIR); @@ -735,9 +743,9 @@ cupsdReadConfiguration(void) Browsing = CUPS_DEFAULT_BROWSING; DefaultShared = CUPS_DEFAULT_DEFAULT_SHARED; -#ifdef HAVE_DNSSD +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) cupsdSetString(&DNSSDSubTypes, "_cups,_print"); -#endif /* HAVE_DNSSD */ +#endif /* HAVE_DNSSD || HAVE_AVAHI */ cupsdSetString(&LPDConfigFile, CUPS_DEFAULT_LPD_CONFIG_FILE); cupsdSetString(&SMBConfigFile, CUPS_DEFAULT_SMB_CONFIG_FILE); @@ -780,21 +788,63 @@ cupsdReadConfiguration(void) cupsdInitEnv(); /* - * Read the configuration file... + * Read the cups-files.conf file... + */ + + if ((fp = cupsFileOpen(CupsFilesFile, "r")) != NULL) + { + status = read_cups_files_conf(fp); + + cupsFileClose(fp); + + if (!status) + { + if (TestConfigFile) + printf("\"%s\" contains errors.\n", CupsFilesFile); + else + syslog(LOG_LPR, "Unable to read \"%s\" due to errors.", + CupsFilesFile); + + return (0); + } + } + else if (errno == ENOENT) + cupsdLogMessage(CUPSD_LOG_INFO, "No %s, using defaults.", CupsFilesFile); + else + { + syslog(LOG_LPR, "Unable to open \"%s\": %s", CupsFilesFile, + strerror(errno)); + return (0); + } + + if (!ErrorLog) + cupsdSetString(&ErrorLog, CUPS_LOGDIR "/error_log"); + + /* + * Read the cupsd.conf file... */ if ((fp = cupsFileOpen(ConfigurationFile, "r")) == NULL) + { + syslog(LOG_LPR, "Unable to open \"%s\": %s", ConfigurationFile, + strerror(errno)); return (0); + } - status = read_configuration(fp); + status = read_cupsd_conf(fp); cupsFileClose(fp); if (!status) - return (0); + { + if (TestConfigFile) + printf("\"%s\" contains errors.\n", ConfigurationFile); + else + syslog(LOG_LPR, "Unable to read \"%s\" due to errors.", + ConfigurationFile); - if (!ErrorLog) - cupsdSetString(&ErrorLog, CUPS_LOGDIR "/error_log"); + return (0); + } RunUser = getuid(); @@ -908,6 +958,13 @@ cupsdReadConfiguration(void) } /* + * Make sure ConfigFilePerm and LogFilePerm have sane values... + */ + + ConfigFilePerm &= 0664; + LogFilePerm &= 0664; + + /* * Open the system log for cupsd if necessary... */ @@ -1068,7 +1125,9 @@ cupsdReadConfiguration(void) Group, 1, 1) < 0 || cupsdCheckPermissions(ServerRoot, "ssl", 0700, RunUser, Group, 1, 0) < 0 || - cupsdCheckPermissions(ServerRoot, "cupsd.conf", ConfigFilePerm, RunUser, + cupsdCheckPermissions(ConfigurationFile, NULL, ConfigFilePerm, RunUser, + Group, 0, 0) < 0 || + cupsdCheckPermissions(CupsFilesFile, NULL, ConfigFilePerm, RunUser, Group, 0, 0) < 0 || cupsdCheckPermissions(ServerRoot, "classes.conf", 0600, RunUser, Group, 0, 0) < 0 || @@ -1083,11 +1142,20 @@ cupsdReadConfiguration(void) * Update TempDir to the default if it hasn't been set already... */ +#ifdef __APPLE__ + if (TempDir && !RunUser && + (!strncmp(TempDir, "/private/tmp", 12) || !strncmp(TempDir, "/tmp", 4))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot use %s for TempDir.", TempDir); + cupsdClearString(&TempDir); + } +#endif /* __APPLE__ */ + if (!TempDir) { #ifdef __APPLE__ if ((tmpdir = getenv("TMPDIR")) != NULL && - strncmp(tmpdir, "/private/tmp", 12)) + strncmp(tmpdir, "/private/tmp", 12) && strncmp(tmpdir, "/tmp", 4)) #else if ((tmpdir = getenv("TMPDIR")) != NULL) #endif /* __APPLE__ */ @@ -1110,13 +1178,13 @@ cupsdReadConfiguration(void) else cupsdSetString(&TempDir, tmpdir); } + } - if (!TempDir) - { - cupsdLogMessage(CUPSD_LOG_INFO, "Using default TempDir of %s/tmp...", - RequestRoot); - cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot); - } + if (!TempDir) + { + cupsdLogMessage(CUPSD_LOG_INFO, "Using default TempDir of %s/tmp...", + RequestRoot); + cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot); } /* @@ -2550,13 +2618,244 @@ parse_protocols(const char *s) /* I - Space-delimited protocols */ /* - * 'read_configuration()' - Read a configuration file. + * 'parse_variable()' - Parse a variable line. */ static int /* O - 1 on success, 0 on failure */ -read_configuration(cups_file_t *fp) /* I - File to read from */ +parse_variable( + const char *filename, /* I - Name of configuration file */ + int linenum, /* I - Line in configuration file */ + const char *line, /* I - Line from configuration file */ + const char *value, /* I - Value from configuration file */ + size_t num_vars, /* I - Number of variables */ + const cupsd_var_t *vars) /* I - Variables */ +{ + size_t i; /* Looping var */ + const cupsd_var_t *var; /* Variables */ + char temp[1024]; /* Temporary string */ + + + for (i = num_vars, var = vars; i > 0; i --, var ++) + if (!_cups_strcasecmp(line, var->name)) + break; + + if (i == 0) + { + /* + * Unknown directive! Output an error message and continue... + */ + + if (!value) + cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value for %s on line %d of %s.", + line, linenum, filename); + else + cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d of %s.", + line, linenum, filename); + + return (0); + } + + switch (var->type) + { + case CUPSD_VARTYPE_INTEGER : + if (!value) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing integer value for %s on line %d of %s.", + line, linenum, filename); + return (0); + } + else if (!isdigit(*value & 255)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad integer value for %s on line %d of %s.", + line, linenum, filename); + return (0); + } + else + { + int n; /* Number */ + char *units; /* Units */ + + n = strtol(value, &units, 0); + + if (units && *units) + { + if (tolower(units[0] & 255) == 'g') + n *= 1024 * 1024 * 1024; + else if (tolower(units[0] & 255) == 'm') + n *= 1024 * 1024; + else if (tolower(units[0] & 255) == 'k') + n *= 1024; + else if (tolower(units[0] & 255) == 't') + n *= 262144; + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown integer value for %s on line %d of %s.", + line, linenum, filename); + return (0); + } + } + + if (n < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad negative integer value for %s on line %d of " + "%s.", line, linenum, filename); + return (0); + } + else + { + *((int *)var->ptr) = n; + } + } + break; + + case CUPSD_VARTYPE_TIME : + if (!value) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing time interval value for %s on line %d of " + "%s.", line, linenum, filename); + return (0); + } + else if (!_cups_strncasecmp(line, "PreserveJob", 11) && + (!_cups_strcasecmp(value, "true") || + !_cups_strcasecmp(value, "on") || + !_cups_strcasecmp(value, "enabled") || + !_cups_strcasecmp(value, "yes"))) + { + *((int *)var->ptr) = INT_MAX; + } + else if (!_cups_strcasecmp(value, "false") || + !_cups_strcasecmp(value, "off") || + !_cups_strcasecmp(value, "disabled") || + !_cups_strcasecmp(value, "no")) + { + *((int *)var->ptr) = 0; + } + else if (!isdigit(*value & 255)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown time interval value for %s on line %d of " + "%s.", line, linenum, filename); + return (0); + } + else + { + double n; /* Number */ + char *units; /* Units */ + + n = strtod(value, &units); + + if (units && *units) + { + if (tolower(units[0] & 255) == 'w') + n *= 7 * 24 * 60 * 60; + else if (tolower(units[0] & 255) == 'd') + n *= 24 * 60 * 60; + else if (tolower(units[0] & 255) == 'h') + n *= 60 * 60; + else if (tolower(units[0] & 255) == 'm') + n *= 60; + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown time interval value for %s on line " + "%d of %s.", line, linenum, filename); + return (0); + } + } + + if (n < 0.0 || n > INT_MAX) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad time value for %s on line %d of %s.", + line, linenum, filename); + return (0); + } + else + { + *((int *)var->ptr) = (int)n; + } + } + break; + + case CUPSD_VARTYPE_BOOLEAN : + if (!value) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing boolean value for %s on line %d of %s.", + line, linenum, filename); + return (0); + } + else if (!_cups_strcasecmp(value, "true") || + !_cups_strcasecmp(value, "on") || + !_cups_strcasecmp(value, "enabled") || + !_cups_strcasecmp(value, "yes") || + atoi(value) != 0) + { + *((int *)var->ptr) = TRUE; + } + else if (!_cups_strcasecmp(value, "false") || + !_cups_strcasecmp(value, "off") || + !_cups_strcasecmp(value, "disabled") || + !_cups_strcasecmp(value, "no") || + !_cups_strcasecmp(value, "0")) + { + *((int *)var->ptr) = FALSE; + } + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown boolean value %s on line %d of %s.", + value, linenum, filename); + return (0); + } + break; + + case CUPSD_VARTYPE_PATHNAME : + if (!value) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing pathname value for %s on line %d of %s.", + line, linenum, filename); + return (0); + } + + if (value[0] == '/') + strlcpy(temp, value, sizeof(temp)); + else + snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value); + + if (access(temp, 0)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "File or directory for \"%s %s\" on line %d of %s " + "does not exist.", line, value, linenum, filename); + return (0); + } + + cupsdSetString((char **)var->ptr, temp); + break; + + case CUPSD_VARTYPE_STRING : + cupsdSetString((char **)var->ptr, value); + break; + } + + return (1); +} + + +/* + * 'read_cupsd_conf()' - Read the cupsd.conf configuration file. + */ + +static int /* O - 1 on success, 0 on failure */ +read_cupsd_conf(cups_file_t *fp) /* I - File to read from */ { - int i; /* Looping var */ int linenum; /* Current line number */ char line[HTTP_MAX_BUFFER], /* Line from file */ @@ -2565,12 +2864,10 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ *value, /* Pointer to value */ *valueptr; /* Pointer into value */ int valuelen; /* Length of value */ - cupsd_var_t const *var; /* Current variable */ http_addrlist_t *addrlist, /* Address list */ *addr; /* Current address */ cups_file_t *incfile; /* Include file */ char incname[1024]; /* Include filename */ - struct group *group; /* Group */ /* @@ -2602,7 +2899,7 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ incname, strerror(errno)); else { - read_configuration(incfile); + read_cupsd_conf(incfile); cupsFileClose(incfile); } } @@ -2626,8 +2923,6 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ if (linenum == 0) return (0); } - else if (!_cups_strcasecmp(line, "FatalErrors")) - FatalErrors = parse_fatal_errors(value); else if (!_cups_strcasecmp(line, "FaxRetryInterval") && value) { JobRetryInterval = atoi(value); @@ -2771,10 +3066,10 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ BrowseLocalProtocols = protocols; } - else if (!_cups_strcasecmp(line, "default_auth_type") && value) + else if (!_cups_strcasecmp(line, "DefaultAuthType") && value) { /* - * default_auth_type {basic,digest,basicdigest,negotiate} + * DefaultAuthType {basic,digest,basicdigest,negotiate} */ if (!_cups_strcasecmp(value, "none")) @@ -2823,81 +3118,6 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ } } #endif /* HAVE_SSL */ - else if (!_cups_strcasecmp(line, "User") && value) - { - /* - * User ID to run as... - */ - - if (isdigit(value[0] & 255)) - { - int uid = atoi(value); - - if (!uid) - cupsdLogMessage(CUPSD_LOG_ERROR, - "Will not use User 0 as specified on line %d " - "for security reasons. You must use a non-" - "privileged account instead.", - linenum); - else - User = atoi(value); - } - else - { - struct passwd *p; /* Password information */ - - endpwent(); - p = getpwnam(value); - - if (p) - { - if (!p->pw_uid) - cupsdLogMessage(CUPSD_LOG_ERROR, - "Will not use User %s (UID=0) as specified on line " - "%d for security reasons. You must use a non-" - "privileged account instead.", - value, linenum); - else - User = p->pw_uid; - } - else - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unknown User \"%s\" on line %d, ignoring.", - value, linenum); - } - } - else if (!_cups_strcasecmp(line, "Group") && value) - { - /* - * Group ID to run as... - */ - - if (isdigit(value[0])) - Group = atoi(value); - else - { - endgrent(); - group = getgrnam(value); - - if (group != NULL) - Group = group->gr_gid; - else - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unknown Group \"%s\" on line %d, ignoring.", - value, linenum); - } - } - else if (!_cups_strcasecmp(line, "SystemGroup") && value) - { - /* - * SystemGroup (admin) group(s)... - */ - - if (!parse_groups(value)) - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unknown SystemGroup \"%s\" on line %d, ignoring.", - value, linenum); - } else if (!_cups_strcasecmp(line, "HostNameLookups") && value) { /* @@ -2976,22 +3196,6 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogTimeFormat %s on line %d.", value, linenum); } - else if (!_cups_strcasecmp(line, "PrintcapFormat") && value) - { - /* - * Format of printcap file? - */ - - if (!_cups_strcasecmp(value, "bsd")) - PrintcapFormat = PRINTCAP_BSD; - else if (!_cups_strcasecmp(value, "plist")) - PrintcapFormat = PRINTCAP_PLIST; - else if (!_cups_strcasecmp(value, "solaris")) - PrintcapFormat = PRINTCAP_SOLARIS; - else - cupsdLogMessage(CUPSD_LOG_WARN, "Unknown PrintcapFormat %s on line %d.", - value, linenum); - } else if (!_cups_strcasecmp(line, "ServerTokens") && value) { /* @@ -3004,19 +3208,20 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ uname(&plat); if (!_cups_strcasecmp(value, "ProductOnly")) - cupsdSetString(&ServerHeader, "CUPS"); + cupsdSetString(&ServerHeader, "CUPS IPP"); else if (!_cups_strcasecmp(value, "Major")) - cupsdSetStringf(&ServerHeader, "CUPS/%d", CUPS_VERSION_MAJOR); + cupsdSetStringf(&ServerHeader, "CUPS/%d IPP/2", CUPS_VERSION_MAJOR); else if (!_cups_strcasecmp(value, "Minor")) - cupsdSetStringf(&ServerHeader, "CUPS/%d.%d", CUPS_VERSION_MAJOR, + cupsdSetStringf(&ServerHeader, "CUPS/%d.%d IPP/2.1", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR); else if (!_cups_strcasecmp(value, "Minimal")) - cupsdSetString(&ServerHeader, CUPS_MINIMAL); + cupsdSetString(&ServerHeader, CUPS_MINIMAL " IPP/2.1"); else if (!_cups_strcasecmp(value, "OS")) - cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s)", plat.sysname); + cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s %s) IPP/2.1", + plat.sysname, plat.release); else if (!_cups_strcasecmp(value, "Full")) - cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s) IPP/2.1", - plat.sysname); + cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s %s; %s) IPP/2.1", + plat.sysname, plat.release, plat.machine); else if (!_cups_strcasecmp(value, "None")) cupsdClearString(&ServerHeader); else @@ -3117,182 +3322,193 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ "line %d.", value, linenum); } #endif /* HAVE_SSL */ + else if (!_cups_strcasecmp(line, "AccessLog") || + !_cups_strcasecmp(line, "CacheDir") || + !_cups_strcasecmp(line, "ConfigFilePerm") || + !_cups_strcasecmp(line, "DataDir") || + !_cups_strcasecmp(line, "DocumentRoot") || + !_cups_strcasecmp(line, "ErrorLog") || + !_cups_strcasecmp(line, "FatalErrors") || + !_cups_strcasecmp(line, "FileDevice") || + !_cups_strcasecmp(line, "FontPath") || + !_cups_strcasecmp(line, "Group") || + !_cups_strcasecmp(line, "LogFilePerm") || + !_cups_strcasecmp(line, "LPDConfigFile") || + !_cups_strcasecmp(line, "PageLog") || + !_cups_strcasecmp(line, "Printcap") || + !_cups_strcasecmp(line, "PrintcapFormat") || + !_cups_strcasecmp(line, "RemoteRoot") || + !_cups_strcasecmp(line, "RequestRoot") || + !_cups_strcasecmp(line, "ServerBin") || + !_cups_strcasecmp(line, "ServerCertificate") || + !_cups_strcasecmp(line, "ServerKey") || + !_cups_strcasecmp(line, "ServerRoot") || + !_cups_strcasecmp(line, "SMBConfigFile") || + !_cups_strcasecmp(line, "StateDir") || + !_cups_strcasecmp(line, "SystemGroup") || + !_cups_strcasecmp(line, "SystemGroupAuthKey") || + !_cups_strcasecmp(line, "TempDir") || + !_cups_strcasecmp(line, "User")) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "Please move \"%s%s%s\" on line %d of %s to the %s file; " + "this will become an error in a future release.", + line, value ? " " : "", value ? value : "", linenum, + ConfigurationFile, CupsFilesFile); + } else + parse_variable(ConfigurationFile, linenum, line, value, + sizeof(cupsd_vars) / sizeof(cupsd_vars[0]), cupsd_vars); + } + + return (1); +} + + +/* + * 'read_cups_files_conf()' - Read the cups-files.conf configuration file. + */ + +static int /* O - 1 on success, 0 on failure */ +read_cups_files_conf(cups_file_t *fp) /* I - File to read from */ +{ + int linenum; /* Current line number */ + char line[HTTP_MAX_BUFFER], /* Line from file */ + *value; /* Value from line */ + struct group *group; /* Group */ + + + /* + * Loop through each line in the file... + */ + + linenum = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + if (!_cups_strcasecmp(line, "FatalErrors")) + FatalErrors = parse_fatal_errors(value); + else if (!_cups_strcasecmp(line, "Group") && value) { /* - * Find a simple variable in the list... + * Group ID to run as... */ - for (i = NUM_VARS, var = variables; i > 0; i --, var ++) - if (!_cups_strcasecmp(line, var->name)) - break; - - if (i == 0) + if (isdigit(value[0])) + Group = atoi(value); + else { - /* - * Unknown directive! Output an error message and continue... - */ + endgrent(); + group = getgrnam(value); - if (!value) - cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value for %s on line %d.", - line, linenum); + if (group != NULL) + Group = group->gr_gid; else - cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d.", - line, linenum); - continue; + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown Group \"%s\" on line %d of %s.", value, + linenum, CupsFilesFile); + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } } + } + else if (!_cups_strcasecmp(line, "PrintcapFormat") && value) + { + /* + * Format of printcap file? + */ - switch (var->type) + if (!_cups_strcasecmp(value, "bsd")) + PrintcapFormat = PRINTCAP_BSD; + else if (!_cups_strcasecmp(value, "plist")) + PrintcapFormat = PRINTCAP_PLIST; + else if (!_cups_strcasecmp(value, "solaris")) + PrintcapFormat = PRINTCAP_SOLARIS; + else { - case CUPSD_VARTYPE_INTEGER : - if (!value) - cupsdLogMessage(CUPSD_LOG_ERROR, - "Missing integer value for %s on line %d.", - line, linenum); - else if (!isdigit(*value & 255)) - cupsdLogMessage(CUPSD_LOG_ERROR, - "Bad integer value for %s on line %d.", - line, linenum); - else - { - int n; /* Number */ - char *units; /* Units */ - - n = strtol(value, &units, 0); - - if (units && *units) - { - if (tolower(units[0] & 255) == 'g') - n *= 1024 * 1024 * 1024; - else if (tolower(units[0] & 255) == 'm') - n *= 1024 * 1024; - else if (tolower(units[0] & 255) == 'k') - n *= 1024; - else if (tolower(units[0] & 255) == 't') - n *= 262144; - else - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unknown integer value for %s on line %d.", - line, linenum); - break; - } - } - - if (n < 0) - cupsdLogMessage(CUPSD_LOG_ERROR, - "Bad negative integer value for %s on line %d.", - line, linenum); - else - *((int *)var->ptr) = n; - } - break; - - case CUPSD_VARTYPE_TIME : - if (!value) - cupsdLogMessage(CUPSD_LOG_ERROR, - "Missing time interval value for %s on line %d.", - line, linenum); - else if (!_cups_strncasecmp(line, "PreserveJob", 11) && - (!_cups_strcasecmp(value, "true") || - !_cups_strcasecmp(value, "on") || - !_cups_strcasecmp(value, "enabled") || - !_cups_strcasecmp(value, "yes"))) - *((int *)var->ptr) = INT_MAX; - else if (!_cups_strcasecmp(value, "false") || - !_cups_strcasecmp(value, "off") || - !_cups_strcasecmp(value, "disabled") || - !_cups_strcasecmp(value, "no")) - *((int *)var->ptr) = 0; - else if (!isdigit(*value & 255)) - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unknown time interval value for %s on line %d.", - line, linenum); - else - { - double n; /* Number */ - char *units; /* Units */ - - n = strtod(value, &units); - - if (units && *units) - { - if (tolower(units[0] & 255) == 'w') - n *= 7 * 24 * 60 * 60; - else if (tolower(units[0] & 255) == 'd') - n *= 24 * 60 * 60; - else if (tolower(units[0] & 255) == 'h') - n *= 60 * 60; - else if (tolower(units[0] & 255) == 'm') - n *= 60; - else - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unknown time interval value for %s on line " - "%d.", line, linenum); - break; - } - } - - if (n < 0.0 || n > INT_MAX) - cupsdLogMessage(CUPSD_LOG_ERROR, - "Bad time value for %s on line %d.", - line, linenum); - else - *((int *)var->ptr) = (int)n; - } - break; + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown PrintcapFormat \"%s\" on line %d of %s.", + value, linenum, CupsFilesFile); + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } + } + else if (!_cups_strcasecmp(line, "SystemGroup") && value) + { + /* + * SystemGroup (admin) group(s)... + */ - case CUPSD_VARTYPE_BOOLEAN : - if (!value) - cupsdLogMessage(CUPSD_LOG_ERROR, - "Missing boolean value for %s on line %d.", - line, linenum); - else if (!_cups_strcasecmp(value, "true") || - !_cups_strcasecmp(value, "on") || - !_cups_strcasecmp(value, "enabled") || - !_cups_strcasecmp(value, "yes") || - atoi(value) != 0) - *((int *)var->ptr) = TRUE; - else if (!_cups_strcasecmp(value, "false") || - !_cups_strcasecmp(value, "off") || - !_cups_strcasecmp(value, "disabled") || - !_cups_strcasecmp(value, "no") || - !_cups_strcasecmp(value, "0")) - *((int *)var->ptr) = FALSE; - else - cupsdLogMessage(CUPSD_LOG_ERROR, - "Unknown boolean value %s on line %d.", - value, linenum); - break; + if (!parse_groups(value)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown SystemGroup \"%s\" on line %d of %s.", value, + linenum, CupsFilesFile); + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } + } + else if (!_cups_strcasecmp(line, "User") && value) + { + /* + * User ID to run as... + */ - case CUPSD_VARTYPE_PATHNAME : - if (!value) - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "Missing pathname value for %s on line %d.", - line, linenum); - break; - } + if (isdigit(value[0] & 255)) + { + int uid = atoi(value); - if (value[0] == '/') - strlcpy(temp, value, sizeof(temp)); - else - snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value); + if (!uid) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Will not use User 0 as specified on line %d of %s " + "for security reasons. You must use a non-" + "privileged account instead.", + linenum, CupsFilesFile); + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } + else + User = atoi(value); + } + else + { + struct passwd *p; /* Password information */ - if (access(temp, 0)) - { - cupsdLogMessage(CUPSD_LOG_ERROR, - "File or directory for \"%s %s\" on line %d " - "does not exist.", line, value, linenum); - break; - } + endpwent(); + p = getpwnam(value); - case CUPSD_VARTYPE_STRING : - cupsdSetString((char **)var->ptr, value); - break; + if (p) + { + if (!p->pw_uid) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Will not use User %s (UID=0) as specified on line " + "%d of %s for security reasons. You must use a " + "non-privileged account instead.", + value, linenum, CupsFilesFile); + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } + else + User = p->pw_uid; + } + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown User \"%s\" on line %d of %s.", + value, linenum, CupsFilesFile); + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } } } + else if (!parse_variable(CupsFilesFile, linenum, line, value, + sizeof(cupsfiles_vars) / sizeof(cupsfiles_vars[0]), + cupsfiles_vars) && + (FatalErrors & CUPSD_FATAL_CONFIG)) + return (0); } return (1); @@ -3864,5 +4080,5 @@ set_policy_defaults(cupsd_policy_t *pol)/* I - Policy */ /* - * End of "$Id: conf.c 10482 2012-05-18 19:51:02Z mike $". + * End of "$Id: conf.c 10824 2013-01-18 19:58:41Z mike $". */ diff --git a/scheduler/conf.h b/scheduler/conf.h index 776a54bf..5ee713ca 100644 --- a/scheduler/conf.h +++ b/scheduler/conf.h @@ -1,5 +1,5 @@ /* - * "$Id: conf.h 10482 2012-05-18 19:51:02Z mike $" + * "$Id: conf.h 10710 2012-11-26 18:26:01Z mike $" * * Configuration file definitions for the CUPS scheduler. * @@ -96,7 +96,9 @@ typedef struct */ VAR char *ConfigurationFile VALUE(NULL), - /* Configuration file to use */ + /* cupsd.conf file to use */ + *CupsFilesFile VALUE(NULL), + /* cups-files.conf file to use */ *ServerName VALUE(NULL), /* FQDN for server */ *ServerAdmin VALUE(NULL), @@ -294,5 +296,5 @@ extern int cupsdWriteErrorLog(int level, const char *message); /* - * End of "$Id: conf.h 10482 2012-05-18 19:51:02Z mike $". + * End of "$Id: conf.h 10710 2012-11-26 18:26:01Z mike $". */ diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h index def25e30..6df5d175 100644 --- a/scheduler/cupsd.h +++ b/scheduler/cupsd.h @@ -1,5 +1,5 @@ /* - * "$Id: cupsd.h 10490 2012-05-21 17:40:22Z mike $" + * "$Id: cupsd.h 10776 2012-12-17 22:17:08Z mike $" * * Main header file for the CUPS scheduler. * @@ -160,13 +160,6 @@ VAR int NeedReload VALUE(RELOAD_ALL), VAR void *DefaultProfile VALUE(0); /* Default security profile */ -#ifdef HAVE_GSSAPI -VAR int KerberosInitialized VALUE(0); - /* Has Kerberos been initialized? */ -VAR krb5_context KerberosContext VALUE(NULL); - /* Kerberos context for credentials */ -#endif /* HAVE_GSSAPI */ - #ifdef HAVE_LAUNCH_H VAR int Launchd VALUE(0); /* Running from launchd */ @@ -237,5 +230,5 @@ extern void cupsdStopServer(void); /* - * End of "$Id: cupsd.h 10490 2012-05-21 17:40:22Z mike $". + * End of "$Id: cupsd.h 10776 2012-12-17 22:17:08Z mike $". */ diff --git a/scheduler/cupsfilter.c b/scheduler/cupsfilter.c index ba7a9ce6..0761cde9 100644 --- a/scheduler/cupsfilter.c +++ b/scheduler/cupsfilter.c @@ -1,9 +1,9 @@ /* - * "$Id: cupsfilter.c 10434 2012-04-23 21:47:41Z mike $" + * "$Id: cupsfilter.c 10869 2013-02-19 23:53:01Z mike $" * * Filtering program for CUPS. * - * Copyright 2007-2012 by Apple Inc. + * Copyright 2007-2013 by Apple Inc. * Copyright 1997-2006 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -409,6 +409,7 @@ main(int argc, /* I - Number of command-line args */ if (srctype) { + /* sscanf return value already checked above */ sscanf(srctype, "%15[^/]/%255s", super, type); if ((src = mimeType(mime, super, type)) == NULL) { @@ -426,6 +427,7 @@ main(int argc, /* I - Number of command-line args */ return (1); } + /* sscanf return value already checked above */ sscanf(dsttype, "%15[^/]/%255s", super, type); if (!_cups_strcasecmp(super, "printer")) dst = printer_type; @@ -915,7 +917,7 @@ exec_filters(mime_type_t *srctype, /* I - Source type */ { int i; /* Looping var */ const char *argv[8], /* Command-line arguments */ - *envp[15], /* Environment variables */ + *envp[16], /* Environment variables */ *temp; /* Temporary string */ char *optstr, /* Filter options */ content_type[1024], /* CONTENT_TYPE */ @@ -1038,7 +1040,8 @@ exec_filters(mime_type_t *srctype, /* I - Source type */ envp[11] = printer_name; envp[12] = rip_max_cache; envp[13] = userenv; - envp[14] = NULL; + envp[14] = "CHARSET=utf-8"; + envp[15] = NULL; for (i = 0; argv[i]; i ++) fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]); @@ -1456,5 +1459,5 @@ usage(const char *opt) /* I - Incorrect option, if any */ /* - * End of "$Id: cupsfilter.c 10434 2012-04-23 21:47:41Z mike $". + * End of "$Id: cupsfilter.c 10869 2013-02-19 23:53:01Z mike $". */ diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c index b575fb43..e491d94d 100644 --- a/scheduler/dirsvc.c +++ b/scheduler/dirsvc.c @@ -1,5 +1,5 @@ /* - * "$Id: dirsvc.c 10472 2012-05-18 02:25:18Z mike $" + * "$Id: dirsvc.c 10641 2012-10-03 14:17:41Z mike $" * * Directory services routines for the CUPS scheduler. * @@ -234,9 +234,12 @@ cupsdStartBrowsing(void) if (FatalErrors & CUPSD_FATAL_BROWSE) cupsdEndProcess(getpid(), 0); - } - avahi_threaded_poll_start(DNSSDMaster); + avahi_threaded_poll_free(DNSSDMaster); + DNSSDMaster = NULL; + } + else + avahi_threaded_poll_start(DNSSDMaster); } # endif /* HAVE_DNSSD */ @@ -456,17 +459,30 @@ cupsdUpdateDNSSDName(void) else # endif /* __APPLE__ */ # ifdef HAVE_AVAHI + if (DNSSDClient) { - cupsdSetString(&DNSSDComputerName, avahi_client_get_host_name(DNSSDClient)); - cupsdSetString(&DNSSDHostName, - avahi_client_get_host_name_fqdn(DNSSDClient)); + const char *host_name = avahi_client_get_host_name(DNSSDClient); + const char *host_fqdn = avahi_client_get_host_name_fqdn(DNSSDClient); + + cupsdSetString(&DNSSDComputerName, host_name ? host_name : ServerName); + + if (host_fqdn) + cupsdSetString(&DNSSDHostName, host_fqdn); + else if (strchr(ServerName, '.')) + cupsdSetString(&DNSSDHostName, ServerName); + else + cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName); } -# else /* HAVE_DNSSD */ + else +# endif /* HAVE_AVAHI */ { cupsdSetString(&DNSSDComputerName, ServerName); - cupsdSetString(&DNSSDHostName, ServerName); + + if (strchr(ServerName, '.')) + cupsdSetString(&DNSSDHostName, ServerName); + else + cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName); } -# endif /* HAVE_AVAHI */ /* * Then (re)register the web interface if enabled... @@ -1650,5 +1666,5 @@ update_smb(int onoff) /* I - 1 = turn on, 0 = turn off */ /* - * End of "$Id: dirsvc.c 10472 2012-05-18 02:25:18Z mike $". + * End of "$Id: dirsvc.c 10641 2012-10-03 14:17:41Z mike $". */ diff --git a/scheduler/ipp.c b/scheduler/ipp.c index 5139ddc8..2c318404 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -1,9 +1,9 @@ /* - * "$Id: ipp.c 10490 2012-05-21 17:40:22Z mike $" + * "$Id: ipp.c 10899 2013-03-11 18:44:36Z mike $" * * IPP routines for the CUPS scheduler. * - * Copyright 2007-2012 by Apple Inc. + * Copyright 2007-2013 by Apple Inc. * Copyright 1997-2007 by Easy Software Products, all rights reserved. * * This file contains Kerberos support code, copyright 2006 by @@ -1285,6 +1285,21 @@ add_job(cupsd_client_t *con, /* I - Client connection */ ipp_attribute_t *media_col, /* media-col attribute */ *media_margin; /* media-*-margin attribute */ ipp_t *unsup_col; /* media-col in unsupported response */ + static const char * const readonly[] =/* List of read-only attributes */ + { + "job-id", + "job-k-octets", + /*"job-impressions",*/ /* For now we allow this since cupsd can't count */ + "job-impressions-completed", + "job-media-sheets", + "job-media-sheets-completed", + "job-state", + "job-state-message", + "job-state-reasons", + "time-at-completed", + "time-at-creation", + "time-at-processing" + }; cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))", @@ -1353,6 +1368,27 @@ add_job(cupsd_client_t *con, /* I - Client connection */ * copies, number-up, and page-ranges... */ + for (i = 0; i < (int)(sizeof(readonly) / sizeof(readonly[0])); i ++) + { + if ((attr = ippFindAttribute(con->request, readonly[i], + IPP_TAG_ZERO)) != NULL) + { + ippDeleteAttribute(con->request, attr); + + if (StrictConformance) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("The '%s' Job Description attribute cannot be " + "supplied in a job creation request."), readonly[i]); + return (NULL); + } + + cupsdLogMessage(CUPSD_LOG_WARN, + "Unexpected '%s' Job Description attribute in a job " + "creation request.", readonly[i]); + } + } + if (filetype && printer->filetypes && !cupsArrayFind(printer->filetypes, filetype)) { @@ -1538,9 +1574,71 @@ add_job(cupsd_client_t *con, /* I - Client connection */ priority); } - if (!ippFindAttribute(con->request, "job-name", IPP_TAG_NAME)) + if ((attr = ippFindAttribute(con->request, "job-name", IPP_TAG_ZERO)) == NULL) ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, "Untitled"); + else if ((attr->value_tag != IPP_TAG_NAME && + attr->value_tag != IPP_TAG_NAMELANG) || + attr->num_values != 1) + { + send_ipp_status(con, IPP_ATTRIBUTES, + _("Bad job-name value: Wrong type or count.")); + if ((attr = ippCopyAttribute(con->response, attr, 0)) != NULL) + attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP; + return (NULL); + } + else + { + const char *ptr; /* Pointer into string */ + + for (ptr = attr->values[0].string.text; *ptr; ptr ++) + { + if ((*ptr & 0xe0) == 0xc0) + { + ptr ++; + if ((*ptr & 0xc0) != 0x80) + break; + } + else if ((*ptr & 0xf0) == 0xe0) + { + ptr ++; + if ((*ptr & 0xc0) != 0x80) + break; + ptr ++; + if ((*ptr & 0xc0) != 0x80) + break; + } + else if ((*ptr & 0xf8) == 0xf0) + { + ptr ++; + if ((*ptr & 0xc0) != 0x80) + break; + ptr ++; + if ((*ptr & 0xc0) != 0x80) + break; + ptr ++; + if ((*ptr & 0xc0) != 0x80) + break; + } + else if (*ptr & 0x80) + break; + } + + if (*ptr || (ptr - attr->values[0].string.text) > (IPP_MAX_NAME - 1)) + { + if (*ptr) + send_ipp_status(con, IPP_ATTRIBUTES, + _("Bad job-name value: Bad UTF-8 sequence.")); + else + send_ipp_status(con, IPP_ATTRIBUTES, + _("Bad job-name value: Name too long.")); + + if ((attr = ippCopyAttribute(con->response, attr, 0)) != NULL) + attr->group_tag = IPP_TAG_UNSUPPORTED_GROUP; + + return (NULL); + } + } if ((job = cupsdAddJob(priority, printer->name)) == NULL) { @@ -2334,6 +2432,21 @@ add_printer(cupsd_client_t *con, /* I - Client connection */ http_uri_status_t uri_status; /* URI separation status */ char old_device_uri[1024]; /* Old device URI */ + static const char * const uri_status_strings[] = + { + "URI too large.", + "Bad arguments to function.", + "Bad resource path.", + "Bad port number.", + "Bad hostname/address.", + "Bad username/password.", + "Bad URI scheme.", + "Bad URI.", + "OK", + "Missing URI scheme.", + "Unknown URI scheme", + "Missing resource path." + }; need_restart_job = 1; @@ -2345,12 +2458,14 @@ add_printer(cupsd_client_t *con, /* I - Client connection */ host, sizeof(host), &port, resource, sizeof(resource)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "%s device-uri: %s", printer->name, + uri_status_strings[uri_status - HTTP_URI_OVERFLOW]); + if (uri_status < HTTP_URI_OK) { send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\"."), attr->values[0].string.text); - cupsdLogMessage(CUPSD_LOG_DEBUG, - "add_printer: httpSeparateURI returned %d", uri_status); return; } @@ -2369,7 +2484,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */ send_ipp_status(con, IPP_NOT_POSSIBLE, _("File device URIs have been disabled. " "To enable, see the FileDevice directive in " - "\"%s/cupsd.conf\"."), + "\"%s/cups-files.conf\"."), ServerRoot); return; } @@ -4813,7 +4928,7 @@ copy_printer_attrs( ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time", ippTimeToDate(curtime)); -#ifdef HAVE_DNSSD +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) if (!ra || cupsArrayFind(ra, "printer-dns-sd-name")) { if (printer->reg_name) @@ -4823,7 +4938,7 @@ copy_printer_attrs( ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_NOVALUE, "printer-dns-sd-name", 0); } -#endif /* HAVE_DNSSD */ +#endif /* HAVE_DNSSD || HAVE_AVAHI */ if (!ra || cupsArrayFind(ra, "printer-error-policy")) ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, @@ -8217,7 +8332,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */ * Grab format from client... */ - if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", super, + if (sscanf(format->values[0].string.text, "%15[^/]/%255[^;]", super, type) != 2) { send_ipp_status(con, IPP_BAD_REQUEST, @@ -8234,7 +8349,7 @@ print_job(cupsd_client_t *con, /* I - Client connection */ * Use default document format... */ - if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2) + if (sscanf(default_format, "%15[^/]/%255[^;]", super, type) != 2) { send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"."), @@ -9448,7 +9563,7 @@ send_document(cupsd_client_t *con, /* I - Client connection */ * Grab format from client... */ - if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", + if (sscanf(format->values[0].string.text, "%15[^/]/%255[^;]", super, type) != 2) { send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"."), @@ -9464,7 +9579,7 @@ send_document(cupsd_client_t *con, /* I - Client connection */ * Use default document format... */ - if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2) + if (sscanf(default_format, "%15[^/]/%255[^;]", super, type) != 2) { send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format-default \"%s\"."), default_format); @@ -10920,7 +11035,8 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ http_status_t status; /* Policy status */ ipp_attribute_t *attr, /* Current attribute */ *auth_info; /* auth-info attribute */ - ipp_attribute_t *format; /* Document-format attribute */ + ipp_attribute_t *format, /* Document-format attribute */ + *name; /* Job-name attribute */ cups_ptype_t dtype; /* Destination type (printer/class) */ char super[MIME_MAX_SUPER], /* Supertype of file */ @@ -10947,7 +11063,7 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ ) { send_ipp_status(con, IPP_ATTRIBUTES, - _("Unsupported compression \"%s\"."), + _("Unsupported 'compression' value \"%s\"."), attr->values[0].string.text); ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD, "compression", NULL, attr->values[0].string.text); @@ -10962,10 +11078,11 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ if ((format = ippFindAttribute(con->request, "document-format", IPP_TAG_MIMETYPE)) != NULL) { - if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]", + if (sscanf(format->values[0].string.text, "%15[^/]/%255[^;]", super, type) != 2) { - send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"."), + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad 'document-format' value \"%s\"."), format->values[0].string.text); return; } @@ -10976,7 +11093,7 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ cupsdLogMessage(CUPSD_LOG_INFO, "Hint: Do you have the raw file printing rules enabled?"); send_ipp_status(con, IPP_DOCUMENT_FORMAT, - _("Unsupported document-format \"%s\"."), + _("Unsupported 'document-format' value \"%s\"."), format->values[0].string.text); ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE, "document-format", NULL, format->values[0].string.text); @@ -10985,6 +11102,86 @@ validate_job(cupsd_client_t *con, /* I - Client connection */ } /* + * Is the job-name valid? + */ + + if ((name = ippFindAttribute(con->request, "job-name", IPP_TAG_ZERO)) != NULL) + { + int bad_name = 0; /* Is the job-name value bad? */ + + if ((name->value_tag != IPP_TAG_NAME && name->value_tag != IPP_TAG_NAMELANG) || + name->num_values != 1) + { + bad_name = 1; + } + else + { + /* + * Validate that job-name conforms to RFC 5198 (Network Unicode) and + * IPP Everywhere requirements for "name" values... + */ + + const unsigned char *nameptr; /* Pointer into "job-name" attribute */ + + for (nameptr = (unsigned char *)name->values[0].string.text; + *nameptr; + nameptr ++) + { + if (*nameptr < ' ' && *nameptr != '\t') + break; + else if (*nameptr == 0x7f) + break; + else if ((*nameptr & 0xe0) == 0xc0) + { + if ((nameptr[1] & 0xc0) != 0x80) + break; + + nameptr ++; + } + else if ((*nameptr & 0xf0) == 0xe0) + { + if ((nameptr[1] & 0xc0) != 0x80 || + (nameptr[2] & 0xc0) != 0x80) + break; + + nameptr += 2; + } + else if ((*nameptr & 0xf8) == 0xf0) + { + if ((nameptr[1] & 0xc0) != 0x80 || + (nameptr[2] & 0xc0) != 0x80 || + (nameptr[3] & 0xc0) != 0x80) + break; + + nameptr += 3; + } + else if (*nameptr & 0x80) + break; + } + + if (*nameptr) + bad_name = 1; + } + + if (bad_name) + { + if (StrictConformance) + { + send_ipp_status(con, IPP_ATTRIBUTES, + _("Unsupported 'job-name' value.")); + ippCopyAttribute(con->response, name, 0); + return; + } + else + { + cupsdLogMessage(CUPSD_LOG_WARN, + "Unsupported 'job-name' value, deleting from request."); + ippDeleteAttribute(con->request, name); + } + } + } + + /* * Is the destination valid? */ @@ -11109,5 +11306,5 @@ validate_user(cupsd_job_t *job, /* I - Job */ /* - * End of "$Id: ipp.c 10490 2012-05-21 17:40:22Z mike $". + * End of "$Id: ipp.c 10899 2013-03-11 18:44:36Z mike $". */ diff --git a/scheduler/job.c b/scheduler/job.c index 73a3a3ab..3b3964b9 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -1,5 +1,5 @@ /* - * "$Id: job.c 10502 2012-05-23 01:36:50Z mike $" + * "$Id: job.c 10776 2012-12-17 22:17:08Z mike $" * * Job management routines for the CUPS scheduler. * @@ -2195,7 +2195,16 @@ cupsdSaveJob(cupsd_job_t *job) /* I - Job */ } if (!cupsdCloseCreatedConfFile(fp, filename)) + { + /* + * Remove backup file and mark this job as clean... + */ + + strlcat(filename, ".O", sizeof(filename)); + unlink(filename); + job->dirty = 0; + } } @@ -2468,8 +2477,10 @@ cupsdSetJobState( * Set the new job state... */ - job->state->values[0].integer = newstate; - job->state_value = newstate; + job->state_value = newstate; + + if (job->state) + job->state->values[0].integer = newstate; switch (newstate) { @@ -2977,7 +2988,8 @@ finalize_job(cupsd_job_t *job, /* I - Job */ * rarely have current information for network devices... */ - if (strncmp(job->printer->device_uri, "usb:", 4)) + if (strncmp(job->printer->device_uri, "usb:", 4) && + strncmp(job->printer->device_uri, "ippusb:", 7)) cupsdSetPrinterReasons(job->printer, "-offline-report"); /* @@ -2988,10 +3000,11 @@ finalize_job(cupsd_job_t *job, /* I - Job */ job->profile = NULL; /* - * Clear the unresponsive job watchdog timer... + * Clear the unresponsive job watchdog timers... */ - job->kill_time = 0; + job->cancel_time = 0; + job->kill_time = 0; /* * Close pipes and status buffer... @@ -3083,6 +3096,8 @@ finalize_job(cupsd_job_t *job, /* I - Job */ exit_code == CUPS_BACKEND_HOLD ? "hold job" : exit_code == CUPS_BACKEND_STOP ? "stop printer" : exit_code == CUPS_BACKEND_CANCEL ? "cancel job" : + exit_code == CUPS_BACKEND_RETRY ? "retry job later" : + exit_code == CUPS_BACKEND_RETRY_CURRENT ? "retry job immediately" : exit_code < 0 ? "crashed" : "unknown"); /* @@ -3645,7 +3660,13 @@ get_options(cupsd_job_t *job, /* I - Job */ attr->value_tag == IPP_TAG_BEGIN_COLLECTION) /* Not yet supported */ continue; - if (!strcmp(attr->name, "job-hold-until")) + if (!strcmp(attr->name, "job-hold-until") || + !strcmp(attr->name, "job-id") || + !strcmp(attr->name, "job-k-octets") || + !strcmp(attr->name, "job-media-sheets") || + !strcmp(attr->name, "job-media-sheets-completed") || + !strcmp(attr->name, "job-state") || + !strcmp(attr->name, "job-state-reasons")) continue; if (!strncmp(attr->name, "job-", 4) && @@ -4272,6 +4293,8 @@ load_request_root(void) else unload_job(job); } + else + free(job); } cupsDirClose(dir); @@ -4363,7 +4386,7 @@ set_time(cupsd_job_t *job, /* I - Job to update */ if (!strcmp(name, "time-at-completed")) { - if (JobHistory < INT_MAX) + if (JobHistory < INT_MAX && attr) job->history_time = attr->values[0].integer + JobHistory; else job->history_time = INT_MAX; @@ -4371,7 +4394,7 @@ set_time(cupsd_job_t *job, /* I - Job to update */ if (job->history_time < JobHistoryUpdate || !JobHistoryUpdate) JobHistoryUpdate = job->history_time; - if (JobFiles < INT_MAX) + if (JobFiles < INT_MAX && attr) job->file_time = attr->values[0].integer + JobFiles; else job->file_time = INT_MAX; @@ -4703,7 +4726,7 @@ update_job(cupsd_job_t *job) /* I - Job to check */ cupsdStopPrinter(job->printer, 1); return; } - else if (cupsdSetPrinterReasons(job->printer, message)) + else if (message[0] && cupsdSetPrinterReasons(job->printer, message)) { event |= CUPSD_EVENT_PRINTER_STATE; @@ -5074,5 +5097,5 @@ update_job_attrs(cupsd_job_t *job, /* I - Job to update */ /* - * End of "$Id: job.c 10502 2012-05-23 01:36:50Z mike $". + * End of "$Id: job.c 10776 2012-12-17 22:17:08Z mike $". */ diff --git a/scheduler/log.c b/scheduler/log.c index 00a0fd95..1ab483d1 100644 --- a/scheduler/log.c +++ b/scheduler/log.c @@ -1,5 +1,5 @@ /* - * "$Id: log.c 10158 2012-01-05 05:50:57Z mike $" + * "$Id: log.c 10752 2012-12-12 18:03:02Z mike $" * * Log file routines for the CUPS scheduler. * @@ -41,6 +41,22 @@ static int log_linesize = 0; /* Size of line for output file */ static char *log_line = NULL; /* Line for output file */ +#ifdef HAVE_VSYSLOG +static const int syslevels[] = /* SYSLOG levels... */ + { + 0, + LOG_EMERG, + LOG_ALERT, + LOG_CRIT, + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG, + LOG_DEBUG + }; +#endif /* HAVE_VSYSLOG */ + /* * Local functions... @@ -543,8 +559,12 @@ cupsdLogMessage(int level, /* I - Log level */ if ((TestConfigFile || !ErrorLog) && level <= CUPSD_LOG_WARN) { va_start(ap, message); +#ifdef HAVE_VSYSLOG + vsyslog(LOG_LPR | syslevels[level], message, ap); +#else vfprintf(stderr, message, ap); putc('\n', stderr); +#endif /* HAVE_VSYSLOG */ va_end(ap); return (1); @@ -984,21 +1004,6 @@ cupsdWriteErrorLog(int level, /* I - Log level */ 'D', 'd' }; -#ifdef HAVE_VSYSLOG - static const int syslevels[] = /* SYSLOG levels... */ - { - 0, - LOG_EMERG, - LOG_ALERT, - LOG_CRIT, - LOG_ERR, - LOG_WARNING, - LOG_NOTICE, - LOG_INFO, - LOG_DEBUG, - LOG_DEBUG - }; -#endif /* HAVE_VSYSLOG */ #ifdef HAVE_VSYSLOG @@ -1098,5 +1103,5 @@ format_log_line(const char *message, /* I - Printf-style format string */ /* - * End of "$Id: log.c 10158 2012-01-05 05:50:57Z mike $". + * End of "$Id: log.c 10752 2012-12-12 18:03:02Z mike $". */ diff --git a/scheduler/main.c b/scheduler/main.c index d3b43a05..58776fea 100644 --- a/scheduler/main.c +++ b/scheduler/main.c @@ -1,5 +1,5 @@ /* - * "$Id: main.c 10431 2012-04-23 19:19:19Z mike $" + * "$Id: main.c 10777 2012-12-17 22:18:10Z mike $" * * Main loop for the CUPS scheduler. * @@ -65,10 +65,15 @@ #if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO) # include <malloc.h> #endif /* HAVE_MALLOC_H && HAVE_MALLINFO */ + #ifdef HAVE_NOTIFY_H # include <notify.h> #endif /* HAVE_NOTIFY_H */ +#ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +#endif /* HAVE_SYS_PARAM_H */ + /* * Local functions... @@ -207,7 +212,6 @@ main(int argc, /* I - Number of command-line args */ char *current; /* Current directory */ - /* * Allocate a buffer for the current working directory to * reduce run-time stack usage; this approximates the @@ -271,6 +275,29 @@ main(int argc, /* I - Number of command-line args */ UseProfiles = 0; break; + case 's' : /* Set cups-files.conf location */ + i ++; + if (i >= argc) + { + _cupsLangPuts(stderr, _("cupsd: Expected cups-files.conf " + "filename after \"-s\" option.")); + usage(1); + } + + if (argv[i][0] != '/') + { + /* + * Relative filename not allowed... + */ + + _cupsLangPuts(stderr, _("cupsd: Relative cups-files.conf " + "filename not allowed.")); + usage(1); + } + + cupsdSetString(&CupsFilesFile, argv[i]); + break; + #ifdef __APPLE__ case 'S' : /* Disable system management functions */ fputs("cupsd: -S (disable system management) for internal " @@ -298,7 +325,39 @@ main(int argc, /* I - Number of command-line args */ } if (!ConfigurationFile) + { cupsdSetString(&ConfigurationFile, CUPS_SERVERROOT "/cupsd.conf"); + cupsdSetString(&CupsFilesFile, CUPS_SERVERROOT "/cups-files.conf"); + } + + if (!CupsFilesFile) + { + char *filename, /* Copy of cupsd.conf filename */ + *slash; /* Final slash in cupsd.conf filename */ + size_t len; /* Size of buffer */ + + len = strlen(ConfigurationFile) + 15; + if ((filename = malloc(len)) == NULL) + { + _cupsLangPrintf(stderr, + _("cupsd: Unable to get path to " + "cups-files.conf file.")); + return (1); + } + + strlcpy(filename, ConfigurationFile, len); + if ((slash = strrchr(filename, '/')) == NULL) + { + _cupsLangPrintf(stderr, + _("cupsd: Unable to get path to " + "cups-files.conf file.")); + return (1); + } + + strlcpy(slash, "/cups-files.conf", len - (slash - filename)); + cupsdSetString(&CupsFilesFile, filename); + free(filename); + } /* * If the user hasn't specified "-f", run in the background... @@ -365,15 +424,15 @@ main(int argc, /* I - Number of command-line args */ } } -#ifdef __OpenBSD__ +#if defined(__OpenBSD__) && OpenBSD < 201211 /* * Call _thread_sys_closefrom() so the child process doesn't reset the * parent's file descriptors to be blocking. This is a workaround for a - * limitation of userland libpthread on OpenBSD. + * limitation of userland libpthread on older versions of OpenBSD. */ _thread_sys_closefrom(0); -#endif /* __OpenBSD__ */ +#endif /* __OpenBSD__ && OpenBSD < 201211 */ /* * Since CoreFoundation and DBUS both create fork-unsafe data on execution of @@ -483,17 +542,11 @@ main(int argc, /* I - Number of command-line args */ */ if (!cupsdReadConfiguration()) - { - if (TestConfigFile) - printf("%s contains errors\n", ConfigurationFile); - else - syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!", - ConfigurationFile); return (1); - } else if (TestConfigFile) { - printf("%s is OK\n", ConfigurationFile); + printf("\"%s\" is OK.\n", CupsFilesFile); + printf("\"%s\" is OK.\n", ConfigurationFile); return (0); } @@ -781,9 +834,9 @@ main(int argc, /* I - Number of command-line args */ * Got an error from select! */ -#ifdef HAVE_DNSSD +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) cupsd_printer_t *p; /* Current printer */ -#endif /* HAVE_DNSSD */ +#endif /* HAVE_DNSSD || HAVE_AVAHI */ if (errno == EINTR) /* Just interrupted by a signal */ @@ -824,13 +877,13 @@ main(int argc, /* I - Number of command-line args */ job->print_pipes[0], job->print_pipes[1], job->back_pipes[0], job->back_pipes[1]); -#ifdef HAVE_DNSSD +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) cupsdLogMessage(CUPSD_LOG_EMERG, "printer[%s] reg_name=\"%s\"", p->name, p->reg_name ? p->reg_name : "(null)"); -#endif /* HAVE_DNSSD */ +#endif /* HAVE_DNSSD || HAVE_AVAHI */ break; } @@ -922,7 +975,7 @@ main(int argc, /* I - Number of command-line args */ */ cupsdDeleteCert(0); - cupsdAddCert(0, "root", NULL); + cupsdAddCert(0, "root", cupsdDefaultAuthType()); } #endif /* !HAVE_AUTHORIZATION_H */ @@ -1114,23 +1167,6 @@ main(int argc, /* I - Number of command-line args */ cupsdStopSystemMonitor(); #endif /* __APPLE__ */ -#ifdef HAVE_GSSAPI - /* - * Free the scheduler's Kerberos context... - */ - -# ifdef __APPLE__ - /* - * If the weak-linked GSSAPI/Kerberos library is not present, don't try - * to use it... - */ - - if (krb5_init_context != NULL) -# endif /* __APPLE__ */ - if (KerberosContext) - krb5_free_context(KerberosContext); -#endif /* HAVE_GSSAPI */ - #ifdef __sgi /* * Remove the fake IRIX lpsched lock file, but only if the existing @@ -2030,5 +2066,5 @@ usage(int status) /* O - Exit status */ /* - * End of "$Id: main.c 10431 2012-04-23 19:19:19Z mike $". + * End of "$Id: main.c 10777 2012-12-17 22:18:10Z mike $". */ diff --git a/scheduler/printers.c b/scheduler/printers.c index cf9cfee6..b56018d5 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -1,5 +1,5 @@ /* - * "$Id: printers.c 10501 2012-05-23 01:19:11Z mike $" + * "$Id: printers.c 10762 2012-12-13 20:28:30Z mike $" * * Printer routines for the CUPS scheduler. * @@ -2074,23 +2074,12 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ { int i; /* Looping var */ char resource[HTTP_MAX_URI]; /* Resource portion of URI */ - int num_air; /* Number of auth-info-required values */ - const char * const *air; /* auth-info-required values */ cupsd_location_t *auth; /* Pointer to authentication element */ const char *auth_supported; /* Authentication supported */ ipp_t *oldattrs; /* Old printer attributes */ ipp_attribute_t *attr; /* Attribute data */ char *name, /* Current user/group name */ *filter; /* Current filter */ - static const char * const air_none[] = - { /* No authentication */ - "none" - }; - static const char * const air_userpass[] = - { /* Basic/Digest authentication */ - "username", - "password" - }; DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name, @@ -2114,19 +2103,6 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ */ auth_supported = "requesting-user-name"; - num_air = 1; - air = air_none; - - if (p->num_auth_info_required > 0 && strcmp(p->auth_info_required[0], "none")) - { - num_air = p->num_auth_info_required; - air = p->auth_info_required; - } - else if (p->type & CUPS_PRINTER_AUTHENTICATED) - { - num_air = 2; - air = air_userpass; - } if (p->type & CUPS_PRINTER_CLASS) snprintf(resource, sizeof(resource), "/classes/%s", p->name); @@ -2205,8 +2181,10 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ "job-k-limit", p->k_limit); ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "job-page-limit", p->page_limit); - ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, - "auth-info-required", num_air, NULL, air); + if (p->num_auth_info_required > 0 && strcmp(p->auth_info_required[0], "none")) + ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "auth-info-required", p->num_auth_info_required, NULL, + p->auth_info_required); if (cupsArrayCount(Banners) > 0) { @@ -4829,13 +4807,13 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ "printer-make-and-model", NULL, "Local System V Printer"); } - else if (!strncmp(p->device_uri, "ipp://", 6) && - (strstr(p->device_uri, "/printers/") != NULL || - strstr(p->device_uri, "/classes/") != NULL || - ((strstr(p->device_uri, "._ipp.") != NULL || - strstr(p->device_uri, "._ipps.") != NULL) && - !strcmp(p->device_uri + strlen(p->device_uri) - 5, - "/cups")))) + else if (((!strncmp(p->device_uri, "ipp://", 6) || + !strncmp(p->device_uri, "ipps://", 7)) && + (strstr(p->device_uri, "/printers/") != NULL || + strstr(p->device_uri, "/classes/") != NULL)) || + ((strstr(p->device_uri, "._ipp.") != NULL || + strstr(p->device_uri, "._ipps.") != NULL) && + !strcmp(p->device_uri + strlen(p->device_uri) - 5, "/cups"))) { /* * Tell the client this is really a hard-wired remote printer. @@ -5339,5 +5317,5 @@ write_xml_string(cups_file_t *fp, /* I - File to write to */ /* - * End of "$Id: printers.c 10501 2012-05-23 01:19:11Z mike $". + * End of "$Id: printers.c 10762 2012-12-13 20:28:30Z mike $". */ diff --git a/scheduler/testmime.c b/scheduler/testmime.c index de495447..aa68a2cd 100644 --- a/scheduler/testmime.c +++ b/scheduler/testmime.c @@ -1,9 +1,9 @@ /* - * "$Id: testmime.c 9862 2011-08-03 02:44:09Z mike $" + * "$Id: testmime.c 10869 2013-02-19 23:53:01Z mike $" * * MIME test program for CUPS. * - * Copyright 2007-2011 by Apple Inc. + * Copyright 2007-2013 by Apple Inc. * Copyright 1997-2006 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -132,7 +132,7 @@ main(int argc, /* I - Number of command-line args */ } else { - sscanf(argv[i], "%15[^/]/%31s", super, type); + sscanf(argv[i], "%15[^/]/%255s", super, type); dst = mimeType(mime, super, type); filters = mimeFilter2(mime, src, srcinfo.st_size, dst, &cost); @@ -527,5 +527,5 @@ type_dir(mime_t *mime, /* I - MIME database */ /* - * End of "$Id: testmime.c 9862 2011-08-03 02:44:09Z mike $". + * End of "$Id: testmime.c 10869 2013-02-19 23:53:01Z mike $". */ |