summaryrefslogtreecommitdiff
path: root/scheduler
diff options
context:
space:
mode:
authorjlovell <jlovell@a1ca3aef-8c08-0410-bb20-df032aa958be>2007-05-04 21:17:48 +0000
committerjlovell <jlovell@a1ca3aef-8c08-0410-bb20-df032aa958be>2007-05-04 21:17:48 +0000
commitb94498cfba64422f0f21181b0c51cc0bed7c7d92 (patch)
treee3bdd0e05380bc8996f35ddb5439ab9044298712 /scheduler
parent323c5de1e804061e344172cc9a9551bb0ee71005 (diff)
downloadcups-b94498cfba64422f0f21181b0c51cc0bed7c7d92.tar.gz
Load cups into easysw/current.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@321 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'scheduler')
-rw-r--r--scheduler/client.c59
-rw-r--r--scheduler/client.h6
-rw-r--r--scheduler/conf.c301
-rw-r--r--scheduler/conf.h10
-rw-r--r--scheduler/cups-driverd.c718
-rw-r--r--scheduler/dirsvc.c6
-rw-r--r--scheduler/ipp.c313
-rw-r--r--scheduler/job.c7
-rw-r--r--scheduler/log.c25
-rw-r--r--scheduler/main.c421
-rw-r--r--scheduler/printers.c21
11 files changed, 1119 insertions, 768 deletions
diff --git a/scheduler/client.c b/scheduler/client.c
index 71ca92880..68439f30e 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -1,5 +1,5 @@
/*
- * "$Id: client.c 6383 2007-03-21 20:01:20Z mike $"
+ * "$Id: client.c 6504 2007-05-02 00:14:56Z mike $"
*
* Client routines for the Common UNIX Printing System (CUPS) scheduler.
*
@@ -2531,10 +2531,10 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
#ifdef DEBUG
cupsdLogMessage(CUPSD_LOG_DEBUG2,
- "cupsdWriteClient(con=%p) %d response=%p, file=%d "
+ "cupsdWriteClient(con=%p) %d response=%p(%d), file=%d "
"pipe_pid=%d state=%d",
- con, con->http.fd, con->response, con->file, con->pipe_pid,
- con->http.state);
+ con, con->http.fd, con->response, con->response->state,
+ con->file, con->pipe_pid, con->http.state);
#endif /* DEBUG */
if (con->http.state != HTTP_GET_SEND &&
@@ -2562,10 +2562,11 @@ cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */
con->file_ready = 0;
}
- if (con->response)
+ if (con->response && con->response->state != IPP_DATA)
{
ipp_state = ippWrite(HTTP(con), con->response);
- bytes = ipp_state != IPP_ERROR && ipp_state != IPP_DATA;
+ bytes = ipp_state != IPP_ERROR &&
+ (con->file >= 0 || ipp_state != IPP_DATA);
}
else if ((bytes = read(con->file, buf, sizeof(buf) - 1)) > 0)
{
@@ -3581,9 +3582,9 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
cupsdSetString(&con->command, CUPS_JAVA);
if (options)
- cupsdSetStringf(&con->options, "%s %s", filename, options);
+ cupsdSetStringf(&con->options, " %s %s", filename, options);
else
- cupsdSetString(&con->options, filename);
+ cupsdSetStringf(&con->options, " %s", filename);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"is_cgi: Returning 1 with command=\"%s\" and options=\"%s\"",
@@ -3602,9 +3603,9 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
cupsdSetString(&con->command, CUPS_PERL);
if (options)
- cupsdSetStringf(&con->options, "%s %s", filename, options);
+ cupsdSetStringf(&con->options, " %s %s", filename, options);
else
- cupsdSetString(&con->options, filename);
+ cupsdSetStringf(&con->options, " %s", filename);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"is_cgi: Returning 1 with command=\"%s\" and options=\"%s\"",
@@ -3623,9 +3624,9 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
cupsdSetString(&con->command, CUPS_PHP);
if (options)
- cupsdSetStringf(&con->options, "%s %s", filename, options);
+ cupsdSetStringf(&con->options, " %s %s", filename, options);
else
- cupsdSetString(&con->options, filename);
+ cupsdSetStringf(&con->options, " %s", filename);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"is_cgi: Returning 1 with command=\"%s\" and options=\"%s\"",
@@ -3644,9 +3645,9 @@ is_cgi(cupsd_client_t *con, /* I - Client connection */
cupsdSetString(&con->command, CUPS_PYTHON);
if (options)
- cupsdSetStringf(&con->options, "%s %s", filename, options);
+ cupsdSetStringf(&con->options, " %s %s", filename, options);
else
- cupsdSetString(&con->options, filename);
+ cupsdSetStringf(&con->options, " %s", filename);
cupsdLogMessage(CUPSD_LOG_DEBUG2,
"is_cgi: Returning 1 with command=\"%s\" and options=\"%s\"",
@@ -4165,8 +4166,9 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
int envc; /* Number of environment variables */
char argbuf[10240], /* Argument buffer */
*argv[100], /* Argument strings */
- *envp[MAX_ENV + 18]; /* Environment variables */
- char content_length[1024], /* CONTENT_LENGTH environment variable */
+ *envp[MAX_ENV + 20]; /* Environment variables */
+ char auth_type[256], /* AUTH_TYPE environment variable */
+ content_length[1024], /* CONTENT_LENGTH environment variable */
content_type[1024], /* CONTENT_TYPE environment variable */
http_cookie[32768], /* HTTP_COOKIE environment variable */
http_referer[1024], /* HTTP_REFERER environment variable */
@@ -4176,6 +4178,7 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
remote_addr[1024], /* REMOTE_ADDR environment variable */
remote_host[1024], /* REMOTE_HOST environment variable */
remote_user[1024], /* REMOTE_USER environment variable */
+ script_filename[1024], /* SCRIPT_FILENAME environment variable */
script_name[1024], /* SCRIPT_NAME environment variable */
server_name[1024], /* SERVER_NAME environment variable */
server_port[1024]; /* SERVER_PORT environment variable */
@@ -4228,6 +4231,9 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
{
commptr = argbuf;
path_info[0] = '\0';
+
+ if (*commptr == ' ')
+ commptr ++;
}
cupsdLogMessage(CUPSD_LOG_INFO, "commptr=\"%s\"", commptr);
@@ -4302,6 +4308,17 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
* Setup the environment variables as needed...
*/
+ if (con->username[0])
+ {
+ snprintf(auth_type, sizeof(auth_type), "AUTH_TYPE=%s",
+ httpGetField(HTTP(con), HTTP_FIELD_AUTHORIZATION));
+
+ if ((uriptr = strchr(auth_type + 10, ' ')) != NULL)
+ *uriptr = '\0';
+ }
+ else
+ auth_type[0] = '\0';
+
if (con->language)
snprintf(lang, sizeof(lang), "LANG=%s.UTF-8", con->language->language);
else
@@ -4318,6 +4335,9 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
if ((uriptr = strchr(script_name, '?')) != NULL)
*uriptr = '\0';
+ snprintf(script_filename, sizeof(script_filename), "SCRIPT_FILENAME=%s%s",
+ DocumentRoot, script_name + 12);
+
sprintf(server_port, "SERVER_PORT=%d", con->serverport);
snprintf(server_name, sizeof(server_name), "SERVER_NAME=%s",
@@ -4325,13 +4345,18 @@ pipe_command(cupsd_client_t *con, /* I - Client connection */
envc = cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0])));
+ if (auth_type[0])
+ envp[envc ++] = auth_type;
+
envp[envc ++] = lang;
envp[envc ++] = "REDIRECT_STATUS=1";
+ envp[envc ++] = "GATEWAY_INTERFACE=CGI/1.1";
envp[envc ++] = server_name;
envp[envc ++] = server_port;
envp[envc ++] = remote_addr;
envp[envc ++] = remote_host;
envp[envc ++] = script_name;
+ envp[envc ++] = script_filename;
if (path_info[0])
envp[envc ++] = path_info;
@@ -4537,5 +4562,5 @@ write_pipe(cupsd_client_t *con) /* I - Client connection */
/*
- * End of "$Id: client.c 6383 2007-03-21 20:01:20Z mike $".
+ * End of "$Id: client.c 6504 2007-05-02 00:14:56Z mike $".
*/
diff --git a/scheduler/client.h b/scheduler/client.h
index de1fb6704..82061b7bb 100644
--- a/scheduler/client.h
+++ b/scheduler/client.h
@@ -1,9 +1,9 @@
/*
- * "$Id: client.h 6383 2007-03-21 20:01:20Z mike $"
+ * "$Id: client.h 6503 2007-05-01 23:06:44Z mike $"
*
* Client definitions for the Common UNIX Printing System (CUPS) scheduler.
*
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
* property of Easy Software Products and are protected by Federal
@@ -138,5 +138,5 @@ extern void cupsdWriteClient(cupsd_client_t *con);
/*
- * End of "$Id: client.h 6383 2007-03-21 20:01:20Z mike $".
+ * End of "$Id: client.h 6503 2007-05-01 23:06:44Z mike $".
*/
diff --git a/scheduler/conf.c b/scheduler/conf.c
index ad463acb6..5fd8f10cf 100644
--- a/scheduler/conf.c
+++ b/scheduler/conf.c
@@ -1,5 +1,5 @@
/*
- * "$Id: conf.c 6436 2007-04-02 23:24:02Z mike $"
+ * "$Id: conf.c 6505 2007-05-03 17:44:22Z mike $"
*
* Configuration routines for the Common UNIX Printing System (CUPS).
*
@@ -23,9 +23,9 @@
*
* Contents:
*
- * cupsdReadConfiguration() - Read the cupsd.conf file.
- * check_permissions() - Fix the mode and ownership of a file or
+ * cupsdCheckPermissions() - Fix the mode and ownership of a file or
* directory.
+ * cupsdReadConfiguration() - Read the cupsd.conf file.
* get_address() - Get an address + port number from a line.
* get_addr_and_mask() - Get an IP address and netmask.
* parse_aaa() - Parse authentication, authorization, and
@@ -45,12 +45,9 @@
#include <stdarg.h>
#include <grp.h>
#include <sys/utsname.h>
+#include <syslog.h>
#include <cups/dir.h>
-#ifdef HAVE_VSYSLOG
-# include <syslog.h>
-#endif /* HAVE_VSYSLOG */
-
/*
* Possibly missing network definitions...
@@ -197,10 +194,6 @@ static unsigned zeros[4] =
/*
* Local functions...
*/
-static int check_permissions(const char *filename,
- const char *suffix, int mode,
- int user, int group, int is_dir,
- int create_dir);
static http_addrlist_t *get_address(const char *value, int defport);
static int get_addr_and_mask(const char *value, unsigned *ip,
unsigned *mask);
@@ -214,6 +207,138 @@ static int read_policy(cups_file_t *fp, char *name, int linenum);
/*
+ * 'cupsdCheckPermissions()' - Fix the mode and ownership of a file or directory.
+ */
+
+int /* O - 0 on success, -1 on error, 1 on warning */
+cupsdCheckPermissions(
+ const char *filename, /* I - File/directory name */
+ const char *suffix, /* I - Additional file/directory name */
+ int mode, /* I - Permissions */
+ int user, /* I - Owner */
+ int group, /* I - Group */
+ int is_dir, /* I - 1 = directory, 0 = file */
+ int create_dir) /* I - 1 = create directory, -1 = create w/o logging, 0 = not */
+{
+ int dir_created = 0; /* Did we create a directory? */
+ char pathname[1024]; /* File name with prefix */
+ struct stat fileinfo; /* Stat buffer */
+
+
+ /*
+ * Prepend the given root to the filename before testing it...
+ */
+
+ if (suffix)
+ {
+ snprintf(pathname, sizeof(pathname), "%s/%s", filename, suffix);
+ filename = pathname;
+ }
+
+ /*
+ * See if we can stat the file/directory...
+ */
+
+ if (stat(filename, &fileinfo))
+ {
+ if (errno == ENOENT && create_dir)
+ {
+ if (create_dir > 0)
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Creating missing directory \"%s\"",
+ filename);
+
+ if (mkdir(filename, mode))
+ {
+ if (create_dir > 0)
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to create directory \"%s\" - %s", filename,
+ strerror(errno));
+ else
+ syslog(LOG_ERR, "Unable to create directory \"%s\" - %s", filename,
+ strerror(errno));
+
+ return (-1);
+ }
+
+ dir_created = 1;
+ }
+ else
+ return (create_dir ? -1 : 1);
+ }
+
+ /*
+ * Make sure it's a regular file...
+ */
+
+ if (!dir_created && !is_dir && !S_ISREG(fileinfo.st_mode))
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a regular file!", filename);
+ return (-1);
+ }
+
+ if (!dir_created && is_dir && !S_ISDIR(fileinfo.st_mode))
+ {
+ if (create_dir >= 0)
+ cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a directory!", filename);
+ else
+ syslog(LOG_ERR, "\"%s\" is not a directory!", filename);
+
+ return (-1);
+ }
+
+ /*
+ * Fix owner, group, and mode as needed...
+ */
+
+ if (dir_created || fileinfo.st_uid != user || fileinfo.st_gid != group)
+ {
+ if (create_dir >= 0)
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Repairing ownership of \"%s\"",
+ filename);
+
+ if (chown(filename, user, group) && !getuid())
+ {
+ if (create_dir >= 0)
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to change ownership of \"%s\" - %s", filename,
+ strerror(errno));
+ else
+ syslog(LOG_ERR, "Unable to change ownership of \"%s\" - %s", filename,
+ strerror(errno));
+
+ return (1);
+ }
+ }
+
+ if (dir_created || (fileinfo.st_mode & 07777) != mode)
+ {
+ if (create_dir >= 0)
+ cupsdLogMessage(CUPSD_LOG_DEBUG, "Repairing access permissions of \"%s\"",
+ filename);
+
+ if (chmod(filename, mode))
+ {
+ if (create_dir >= 0)
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to change permissions of \"%s\" - %s", filename,
+ strerror(errno));
+ else
+ syslog(LOG_ERR, "Unable to change permissions of \"%s\" - %s", filename,
+ strerror(errno));
+
+ return (1);
+ }
+ }
+
+ /*
+ * Everything is OK...
+ */
+
+ return (0);
+}
+
+
+/*
* 'cupsdReadConfiguration()' - Read the cupsd.conf file.
*/
@@ -658,20 +783,28 @@ cupsdReadConfiguration(void)
* writable by the user and group in the cupsd.conf file...
*/
- if (check_permissions(CacheDir, NULL, 0775, RunUser, Group, 1, 1) < 0 ||
- check_permissions(StateDir, NULL, 0755, RunUser, Group, 1, 1) < 0 ||
- check_permissions(StateDir, "certs", RunUser ? 0711 : 0511, User,
- SystemGroupIDs[0], 1, 1) < 0 ||
- check_permissions(ServerRoot, NULL, 0755, RunUser, Group, 1, 0) < 0 ||
- check_permissions(ServerRoot, "ppd", 0755, RunUser, Group, 1, 1) < 0 ||
- check_permissions(ServerRoot, "ssl", 0700, RunUser, Group, 1, 0) < 0 ||
- check_permissions(ServerRoot, "cupsd.conf", ConfigFilePerm, RunUser,
- Group, 0, 0) < 0 ||
- check_permissions(ServerRoot, "classes.conf", 0600, RunUser, Group,
- 0, 0) < 0 ||
- check_permissions(ServerRoot, "printers.conf", 0600, RunUser, Group,
- 0, 0) < 0 ||
- check_permissions(ServerRoot, "passwd.md5", 0600, User, Group, 0, 0) < 0)
+ if (cupsdCheckPermissions(RequestRoot, NULL, 0710, RunUser,
+ Group, 1, 1) < 0 ||
+ cupsdCheckPermissions(CacheDir, NULL, 0775, RunUser,
+ Group, 1, 1) < 0 ||
+ cupsdCheckPermissions(StateDir, NULL, 0755, RunUser,
+ Group, 1, 1) < 0 ||
+ cupsdCheckPermissions(StateDir, "certs", RunUser ? 0711 : 0511, User,
+ SystemGroupIDs[0], 1, 1) < 0 ||
+ cupsdCheckPermissions(ServerRoot, NULL, 0755, RunUser,
+ Group, 1, 0) < 0 ||
+ cupsdCheckPermissions(ServerRoot, "ppd", 0755, RunUser,
+ Group, 1, 1) < 0 ||
+ cupsdCheckPermissions(ServerRoot, "ssl", 0700, RunUser,
+ Group, 1, 0) < 0 ||
+ cupsdCheckPermissions(ServerRoot, "cupsd.conf", ConfigFilePerm, RunUser,
+ Group, 0, 0) < 0 ||
+ cupsdCheckPermissions(ServerRoot, "classes.conf", 0600, RunUser,
+ Group, 0, 0) < 0 ||
+ cupsdCheckPermissions(ServerRoot, "printers.conf", 0600, RunUser,
+ Group, 0, 0) < 0 ||
+ cupsdCheckPermissions(ServerRoot, "passwd.md5", 0600, User,
+ Group, 0, 0) < 0)
return (0);
/*
@@ -710,13 +843,9 @@ cupsdReadConfiguration(void)
}
/*
- * Make sure the request and temporary directories have the right
- * permissions...
+ * Make sure the temporary directory has the right permissions...
*/
- if (check_permissions(RequestRoot, NULL, 0710, RunUser, Group, 1, 1) < 0)
- return (0);
-
if (!strncmp(TempDir, RequestRoot, strlen(RequestRoot)) ||
access(TempDir, 0))
{
@@ -725,7 +854,7 @@ cupsdReadConfiguration(void)
* is under the spool directory or does not exist...
*/
- if (check_permissions(TempDir, NULL, 01770, RunUser, Group, 1, 1) < 0)
+ if (cupsdCheckPermissions(TempDir, NULL, 01770, RunUser, Group, 1, 1) < 0)
return (0);
}
@@ -1133,114 +1262,6 @@ cupsdReadConfiguration(void)
/*
- * 'check_permissions()' - Fix the mode and ownership of a file or directory.
- */
-
-static int /* O - 0 on success, -1 on error, 1 on warning */
-check_permissions(const char *filename, /* I - File/directory name */
- const char *suffix, /* I - Additional file/directory name */
- int mode, /* I - Permissions */
- int user, /* I - Owner */
- int group, /* I - Group */
- int is_dir, /* I - 1 = directory, 0 = file */
- int create_dir)/* I - 1 = create directory, 0 = not */
-{
- int dir_created = 0; /* Did we create a directory? */
- char pathname[1024]; /* File name with prefix */
- struct stat fileinfo; /* Stat buffer */
-
-
- /*
- * Prepend the given root to the filename before testing it...
- */
-
- if (suffix)
- {
- snprintf(pathname, sizeof(pathname), "%s/%s", filename, suffix);
- filename = pathname;
- }
-
- /*
- * See if we can stat the file/directory...
- */
-
- if (stat(filename, &fileinfo))
- {
- if (errno == ENOENT && create_dir)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Creating missing directory \"%s\"",
- filename);
-
- if (mkdir(filename, mode))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to create directory \"%s\" - %s", filename,
- strerror(errno));
- return (-1);
- }
-
- dir_created = 1;
- }
- else
- return (create_dir ? -1 : 1);
- }
-
- /*
- * Make sure it's a regular file...
- */
-
- if (!dir_created && !is_dir && !S_ISREG(fileinfo.st_mode))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a regular file!", filename);
- return (-1);
- }
-
- if (!dir_created && is_dir && !S_ISDIR(fileinfo.st_mode))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a directory!", filename);
- return (-1);
- }
-
- /*
- * Fix owner, group, and mode as needed...
- */
-
- if (dir_created || fileinfo.st_uid != user || fileinfo.st_gid != group)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Repairing ownership of \"%s\"", filename);
-
- if (chown(filename, user, group) && !getuid())
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to change ownership of \"%s\" - %s", filename,
- strerror(errno));
- return (1);
- }
- }
-
- if (dir_created || (fileinfo.st_mode & 07777) != mode)
- {
- cupsdLogMessage(CUPSD_LOG_DEBUG, "Repairing access permissions of \"%s\"",
- filename);
-
- if (chmod(filename, mode))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to change permissions of \"%s\" - %s", filename,
- strerror(errno));
- return (1);
- }
- }
-
- /*
- * Everything is OK...
- */
-
- return (0);
-}
-
-
-/*
* 'get_address()' - Get an address + port number from a line.
*/
@@ -3352,5 +3373,5 @@ read_policy(cups_file_t *fp, /* I - Configuration file */
/*
- * End of "$Id: conf.c 6436 2007-04-02 23:24:02Z mike $".
+ * End of "$Id: conf.c 6505 2007-05-03 17:44:22Z mike $".
*/
diff --git a/scheduler/conf.h b/scheduler/conf.h
index 6bb223ecb..87eb94eba 100644
--- a/scheduler/conf.h
+++ b/scheduler/conf.h
@@ -1,5 +1,5 @@
/*
- * "$Id: conf.h 6436 2007-04-02 23:24:02Z mike $"
+ * "$Id: conf.h 6490 2007-04-30 18:09:30Z mike $"
*
* Configuration file definitions for the Common UNIX Printing System (CUPS)
* scheduler.
@@ -218,8 +218,11 @@ VAR char *SystemGroupAuthKey VALUE(NULL);
* Prototypes...
*/
+extern int cupsdCheckPermissions(const char *filename,
+ const char *suffix, int mode,
+ int user, int group, int is_dir,
+ int create_dir);
extern char *cupsdGetDateTime(time_t t);
-extern int cupsdReadConfiguration(void);
#ifdef HAVE_GSSAPI
extern int cupsdLogGSSMessage(int level, int major_status,
int minor_status,
@@ -232,8 +235,9 @@ __attribute__ ((__format__ (__printf__, 2, 3)))
;
extern int cupsdLogPage(cupsd_job_t *job, const char *page);
extern int cupsdLogRequest(cupsd_client_t *con, http_status_t code);
+extern int cupsdReadConfiguration(void);
/*
- * End of "$Id: conf.h 6436 2007-04-02 23:24:02Z mike $".
+ * End of "$Id: conf.h 6490 2007-04-30 18:09:30Z mike $".
*/
diff --git a/scheduler/cups-driverd.c b/scheduler/cups-driverd.c
index e2898ad29..1a7a3931d 100644
--- a/scheduler/cups-driverd.c
+++ b/scheduler/cups-driverd.c
@@ -1,5 +1,5 @@
/*
- * "$Id: cups-driverd.c 6377 2007-03-21 07:17:11Z mike $"
+ * "$Id: cups-driverd.c 6508 2007-05-03 20:07:14Z mike $"
*
* PPD/driver support for the Common UNIX Printing System (CUPS).
*
@@ -32,6 +32,7 @@
* cat_ppd() - Copy a PPD file to stdout.
* compare_names() - Compare PPD filenames for sorting.
* compare_ppds() - Compare PPD file make and model names for sorting.
+ * free_array() - Free an array of strings.
* list_ppds() - List PPD files.
* load_ppds() - Load PPD files recursively.
* load_drivers() - Load driver-generated PPD files.
@@ -54,6 +55,16 @@ extern cups_encoding_t _ppdGetEncoding(const char *name);
/*
+ * Constants...
+ */
+
+#define PPD_SYNC 0x50504433 /* Sync word for ppds.dat (PPD3) */
+#define PPD_MAX_LANG 32 /* Maximum languages */
+#define PPD_MAX_PROD 8 /* Maximum products */
+#define PPD_MAX_VERS 8 /* Maximum versions */
+
+
+/*
* PPD information structures...
*/
@@ -61,14 +72,17 @@ typedef struct /**** PPD record ****/
{
time_t mtime; /* Modification time */
size_t size; /* Size in bytes */
- char name[512 - sizeof(time_t) - sizeof(size_t)],
- /* PPD name */
- natural_language[6], /* LanguageVersion */
- product[122], /* Product */
+ char name[512], /* PPD name */
+ languages[PPD_MAX_LANG][6],
+ /* LanguageVersion/cupsLanguages */
+ products[PPD_MAX_PROD][128],
+ /* Product strings */
+ psversions[PPD_MAX_VERS][32],
+ /* PSVersion strings */
make[128], /* Manufacturer */
make_and_model[128], /* NickName/ModelName */
device_id[128]; /* IEEE 1284 Device ID */
-} ppd_rec_t;
+} ppd_rec_t;
typedef struct /**** In-memory record ****/
{
@@ -92,18 +106,20 @@ int ChangedPPD; /* Did we change the PPD database? */
* Local functions...
*/
-static ppd_info_t *add_ppd(const char *name, const char *natural_language,
+static ppd_info_t *add_ppd(const char *name, const char *language,
const char *make, const char *make_and_model,
const char *device_id, const char *product,
- time_t mtime, size_t size);
-static int cat_ppd(const char *name);
+ const char *psversion, time_t mtime,
+ size_t size);
+static int cat_ppd(const char *name, int request_id);
static int compare_names(const ppd_info_t *p0,
const ppd_info_t *p1);
static int compare_ppds(const ppd_info_t *p0,
const ppd_info_t *p1);
+static void free_array(cups_array_t *a);
static int list_ppds(int request_id, int limit, const char *opt);
static int load_drivers(void);
-static int load_ppds(const char *d, const char *p);
+static int load_ppds(const char *d, const char *p, int descend);
/*
@@ -123,12 +139,15 @@ main(int argc, /* I - Number of command-line args */
*/
if (argc == 3 && !strcmp(argv[1], "cat"))
- return (cat_ppd(argv[2]));
+ return (cat_ppd(argv[2], 0));
+ else if (argc == 4 && !strcmp(argv[1], "get"))
+ return (cat_ppd(argv[3], atoi(argv[2])));
else if (argc == 5 && !strcmp(argv[1], "list"))
return (list_ppds(atoi(argv[2]), atoi(argv[3]), argv[4]));
else
{
fputs("Usage: cups-driverd cat ppd-name\n", stderr);
+ fputs("Usage: cups-driverd get request_id ppd-name\n", stderr);
fputs("Usage: cups-driverd list request_id limit options\n", stderr);
return (1);
}
@@ -141,11 +160,12 @@ main(int argc, /* I - Number of command-line args */
static ppd_info_t * /* O - PPD */
add_ppd(const char *name, /* I - PPD name */
- const char *natural_language, /* I - Language(s) */
+ const char *language, /* I - LanguageVersion */
const char *make, /* I - Manufacturer */
const char *make_and_model, /* I - NickName/ModelName */
const char *device_id, /* I - 1284DeviceID */
const char *product, /* I - Product */
+ const char *psversion, /* I - PSVersion */
time_t mtime, /* I - Modification time */
size_t size) /* I - File size */
{
@@ -172,7 +192,8 @@ add_ppd(const char *name, /* I - PPD name */
if (ppd == NULL)
{
- fprintf(stderr, "ERROR: [cups-driverd] Ran out of memory for %d PPD files!\n",
+ fprintf(stderr,
+ "ERROR: [cups-driverd] Ran out of memory for %d PPD files!\n",
AllocPPDs);
return (NULL);
}
@@ -194,9 +215,11 @@ add_ppd(const char *name, /* I - PPD name */
ppd->record.size = size;
strlcpy(ppd->record.name, name, sizeof(ppd->record.name));
- strlcpy(ppd->record.natural_language, natural_language,
- sizeof(ppd->record.natural_language));
- strlcpy(ppd->record.product, product, sizeof(ppd->record.product));
+ strlcpy(ppd->record.languages[0], language,
+ sizeof(ppd->record.languages[0]));
+ strlcpy(ppd->record.products[0], product, sizeof(ppd->record.products[0]));
+ strlcpy(ppd->record.psversions[0], psversion,
+ sizeof(ppd->record.psversions[0]));
strlcpy(ppd->record.make, make, sizeof(ppd->record.make));
strlcpy(ppd->record.make_and_model, make_and_model,
sizeof(ppd->record.make_and_model));
@@ -207,7 +230,8 @@ add_ppd(const char *name, /* I - PPD name */
* Foomatic drivers...
*/
- if ((recommended = strstr(ppd->record.make_and_model, " (recommended)")) != NULL)
+ if ((recommended = strstr(ppd->record.make_and_model,
+ " (recommended)")) != NULL)
*recommended = '\0';
/*
@@ -223,11 +247,13 @@ add_ppd(const char *name, /* I - PPD name */
*/
static int /* O - Exit code */
-cat_ppd(const char *name) /* I - PPD name */
+cat_ppd(const char *name, /* I - PPD name */
+ int request_id) /* I - Request ID for response? */
{
char scheme[256], /* Scheme from PPD name */
*sptr; /* Pointer into scheme */
char line[1024]; /* Line/filename */
+ char message[2048]; /* status-message */
/*
@@ -252,6 +278,8 @@ cat_ppd(const char *name) /* I - PPD name */
else
scheme[0] = '\0';
+ puts("Content-Type: application/ipp\n");
+
if (scheme[0])
{
/*
@@ -273,6 +301,21 @@ cat_ppd(const char *name) /* I - PPD name */
fprintf(stderr, "ERROR: [cups-driverd] Unable to access \"%s\" - %s\n",
line, strerror(errno));
+
+ if (request_id > 0)
+ {
+ snprintf(message, sizeof(message), "Unable to access \"%s\" - %s",
+ line, strerror(errno));
+
+ cupsdSendIPPHeader(IPP_NOT_FOUND, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPString(IPP_TAG_TEXT, "status-message", message);
+ cupsdSendIPPTrailer();
+ }
+
return (1);
}
@@ -280,6 +323,16 @@ cat_ppd(const char *name) /* I - PPD name */
* Yes, let it cat the PPD file...
*/
+ if (request_id)
+ {
+ cupsdSendIPPHeader(IPP_OK, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPTrailer();
+ }
+
if (execl(line, scheme, "cat", name, (char *)NULL))
{
/*
@@ -308,6 +361,20 @@ cat_ppd(const char *name) /* I - PPD name */
*/
fprintf(stderr, "ERROR: [cups-driverd] Bad PPD name \"%s\"!\n", name);
+
+ if (request_id)
+ {
+ snprintf(message, sizeof(message), "Bad PPD name \"%s\"!", name);
+
+ cupsdSendIPPHeader(IPP_OK, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPString(IPP_TAG_TEXT, "status-message", message);
+ cupsdSendIPPTrailer();
+ }
+
return (1);
}
@@ -315,17 +382,85 @@ cat_ppd(const char *name) /* I - PPD name */
* Try opening the file...
*/
- if ((datadir = getenv("CUPS_DATADIR")) == NULL)
- datadir = CUPS_DATADIR;
+#ifdef __APPLE__
+ if (!strncmp(name, "System/Library/Printers/PPDs/Contents/Resources/", 48) ||
+ !strncmp(name, "Library/Printers/PPDs/Contents/Resources/", 41))
+ {
+ /*
+ * Map ppd-name to Mac OS X standard locations...
+ */
+
+ snprintf(line, sizeof(line), "/%s", name);
+ }
+ else
+
+#elif defined(__linux)
+ if (!strncmp(name, "lsb/usr/", 8))
+ {
+ /*
+ * Map ppd-name to LSB standard /usr/share/ppd location...
+ */
+
+ snprintf(line, sizeof(line), "/usr/share/ppd/%s", name + 8);
+ }
+ else if (!strncmp(name, "lsb/opt/", 8))
+ {
+ /*
+ * Map ppd-name to LSB standard /opt/share/ppd location...
+ */
+
+ snprintf(line, sizeof(line), "/opt/share/ppd/%s", name + 8);
+ }
+ else if (!strncmp(name, "lsb/local/", 10))
+ {
+ /*
+ * Map ppd-name to LSB standard /usr/local/share/ppd location...
+ */
+
+ snprintf(line, sizeof(line), "/usr/local/share/ppd/%s", name + 10);
+ }
+ else
+
+#endif /* __APPLE__ */
+ {
+ if ((datadir = getenv("CUPS_DATADIR")) == NULL)
+ datadir = CUPS_DATADIR;
+
+ snprintf(line, sizeof(line), "%s/model/%s", datadir, name);
+ }
- snprintf(line, sizeof(line), "%s/model/%s", datadir, name);
if ((fp = cupsFileOpen(line, "r")) == NULL)
{
fprintf(stderr, "ERROR: [cups-driverd] Unable to open \"%s\" - %s\n",
line, strerror(errno));
+
+ if (request_id)
+ {
+ snprintf(message, sizeof(message), "Unable to open \"%s\" - %s",
+ line, strerror(errno));
+
+ cupsdSendIPPHeader(IPP_NOT_FOUND, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPString(IPP_TAG_TEXT, "status-message", message);
+ cupsdSendIPPTrailer();
+ }
+
return (1);
}
+ if (request_id)
+ {
+ cupsdSendIPPHeader(IPP_OK, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language",
+ "en-US");
+ cupsdSendIPPTrailer();
+ }
+
/*
* Now copy the file to stdout...
*/
@@ -377,8 +512,27 @@ compare_ppds(const ppd_info_t *p0, /* I - First PPD file */
p1->record.make_and_model)) != 0)
return (diff);
else
- return (strcasecmp(p0->record.natural_language,
- p1->record.natural_language));
+ return (strcasecmp(p0->record.languages[0],
+ p1->record.languages[0]));
+}
+
+
+/*
+ * 'free_array()' - Free an array of strings.
+ */
+
+static void
+free_array(cups_array_t *a) /* I - Array to free */
+{
+ char *ptr; /* Pointer to string */
+
+
+ for (ptr = (char *)cupsArrayFirst(a);
+ ptr;
+ ptr = (char *)cupsArrayNext(a))
+ free(ptr);
+
+ cupsArrayDelete(a);
}
@@ -391,7 +545,7 @@ list_ppds(int request_id, /* I - Request ID */
int limit, /* I - Limit */
const char *opt) /* I - Option argument */
{
- int i; /* Looping var */
+ int i, j; /* Looping vars */
int count; /* Number of PPDs to send */
ppd_info_t *ppd; /* Current PPD file */
cups_file_t *fp; /* ppds.dat file */
@@ -403,17 +557,27 @@ list_ppds(int request_id, /* I - Request ID */
int num_options; /* Number of options */
cups_option_t *options; /* Options */
const char *requested, /* requested-attributes option */
- *make; /* ppd-make option */
- int send_natural_language, /* Send ppd-natural-language attribute? */
- send_make, /* Send ppd-make attribute? */
- send_make_and_model, /* Send ppd-make-and-model attribute? */
- send_name, /* Send ppd-name attribute? */
- send_device_id, /* Send ppd-device-id attribute? */
- send_product; /* Send ppd-product attribute? */
-
-
- fprintf(stderr, "DEBUG2: [cups-driverd] list_ppds(request_id=%d, limit=%d, opt=\"%s\"\n",
- request_id, limit, opt);
+ *device_id, /* ppd-device-id option */
+ *language, /* ppd-natural-language option */
+ *make, /* ppd-make option */
+ *make_and_model, /* ppd-make-and-model option */
+ *product, /* ppd-product option */
+ *psversion; /* ppd-psversion option */
+ int mam_len, /* Length of ppd-make-and-model */
+ device_id_len, /* Length of ppd-device-id */
+ send_natural_language, /* Send ppd-natural-language? */
+ send_make, /* Send ppd-make? */
+ send_make_and_model, /* Send ppd-make-and-model? */
+ send_name, /* Send ppd-name? */
+ send_device_id, /* Send ppd-device-id? */
+ send_product, /* Send ppd-product? */
+ send_psversion, /* Send ppd-psversion? */
+ sent_header; /* Sent the IPP header? */
+
+
+ fprintf(stderr,
+ "DEBUG2: [cups-driverd] list_ppds(request_id=%d, limit=%d, "
+ "opt=\"%s\"\n", request_id, limit, opt);
/*
* See if we a PPD database file...
@@ -428,45 +592,48 @@ list_ppds(int request_id, /* I - Request ID */
cups_cachedir = CUPS_CACHEDIR;
snprintf(filename, sizeof(filename), "%s/ppds.dat", cups_cachedir);
- if (!stat(filename, &fileinfo) &&
- (fileinfo.st_size % sizeof(ppd_rec_t)) == 0 &&
- (NumPPDs = fileinfo.st_size / sizeof(ppd_rec_t)) > 0)
+ if ((fp = cupsFileOpen(filename, "r")) != NULL)
{
/*
- * We have a ppds.dat file, so read it!
+ * See if we have the right sync word...
*/
- AllocPPDs = NumPPDs;
+ unsigned ppdsync; /* Sync word */
- if ((PPDs = malloc(sizeof(ppd_info_t) * NumPPDs)) == NULL)
+ if (cupsFileRead(fp, (char *)&ppdsync, sizeof(ppdsync))
+ == sizeof(ppdsync) &&
+ ppdsync == PPD_SYNC &&
+ !stat(filename, &fileinfo) &&
+ ((fileinfo.st_size - sizeof(ppdsync)) % sizeof(ppd_rec_t)) == 0 &&
+ (NumPPDs = (fileinfo.st_size - sizeof(ppdsync)) /
+ sizeof(ppd_rec_t)) > 0)
{
- fprintf(stderr,
- "ERROR: [cups-driverd] Unable to allocate memory for %d "
- "PPD files!\n", NumPPDs);
- NumPPDs = 0;
- AllocPPDs = 0;
- }
- else if ((fp = cupsFileOpen(filename, "r")) != NULL)
- {
- for (i = NumPPDs, ppd = PPDs; i > 0; i --, ppd ++)
+ /*
+ * We have a ppds.dat file, so read it!
+ */
+
+ if ((PPDs = malloc(sizeof(ppd_info_t) * NumPPDs)) == NULL)
+ fprintf(stderr,
+ "ERROR: [cups-driverd] Unable to allocate memory for %d "
+ "PPD files!\n", NumPPDs);
+ else
{
- cupsFileRead(fp, (char *)&(ppd->record), sizeof(ppd_rec_t));
- ppd->found = 0;
- }
+ AllocPPDs = NumPPDs;
- cupsFileClose(fp);
+ for (i = NumPPDs, ppd = PPDs; i > 0; i --, ppd ++)
+ {
+ cupsFileRead(fp, (char *)&(ppd->record), sizeof(ppd_rec_t));
+ ppd->found = 0;
+ }
- fprintf(stderr, "INFO: [cups-driverd] Read \"%s\", %d PPDs...\n",
- filename, NumPPDs);
- }
- else
- {
- fprintf(stderr, "ERROR: [cups-driverd] Unable to read \"%s\" - %s\n", filename,
- strerror(errno));
- NumPPDs = 0;
+ fprintf(stderr, "INFO: [cups-driverd] Read \"%s\", %d PPDs...\n",
+ filename, NumPPDs);
+ }
}
- }
+ cupsFileClose(fp);
+ }
+
/*
* Load all PPDs in the specified directory and below...
*/
@@ -477,7 +644,31 @@ list_ppds(int request_id, /* I - Request ID */
cups_datadir = CUPS_DATADIR;
snprintf(model, sizeof(model), "%s/model", cups_datadir);
- load_ppds(model, "");
+ load_ppds(model, "", 1);
+
+#ifdef __APPLE__
+ /*
+ * Load PPDs from standard Mac OS X locations...
+ */
+
+ 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/PPDs/Contents/Resources",
+ "System/Library/Printers/PPDs/Contents/Resources", 0);
+ load_ppds("/System/Library/Printers/PPDs/Contents/Resources/en.lproj",
+ "System/Library/Printers/PPDs/Contents/Resources/en.lproj", 0);
+
+#elif defined(__linux)
+ /*
+ * Load PPDs from LSB-defined locations...
+ */
+
+ load_ppds("/usr/local/share/ppds", "lsb/local", 1);
+ load_ppds("/usr/share/ppds", "lsb/usr", 1);
+ load_ppds("/opt/share/ppds", "lsb/opt", 1);
+#endif /* __APPLE__ */
/*
* Cull PPD files that are no longer present...
@@ -513,6 +704,11 @@ list_ppds(int request_id, /* I - Request ID */
{
if ((fp = cupsFileOpen(filename, "w")) != NULL)
{
+ unsigned ppdsync = PPD_SYNC; /* Sync word */
+
+
+ cupsFileWrite(fp, (char *)&ppdsync, sizeof(ppdsync));
+
for (i = NumPPDs, ppd = PPDs; i > 0; i --, ppd ++)
cupsFileWrite(fp, (char *)&(ppd->record), sizeof(ppd_rec_t));
@@ -538,7 +734,7 @@ list_ppds(int request_id, /* I - Request ID */
* Add the raw driver...
*/
- add_ppd("raw", "en", "Raw", "Raw Queue", "", "", 0, 0);
+ add_ppd("raw", "en", "Raw", "Raw Queue", "", "", "", 0, 0);
/*
* Sort the PPDs by make and model...
@@ -552,12 +748,46 @@ list_ppds(int request_id, /* I - Request ID */
* Send IPP attributes...
*/
- num_options = cupsParseOptions(opt, 0, &options);
- requested = cupsGetOption("requested-attributes", num_options, options);
- make = cupsGetOption("ppd-make", num_options, options);
+ num_options = cupsParseOptions(opt, 0, &options);
+ requested = cupsGetOption("requested-attributes", num_options, options);
+ device_id = cupsGetOption("ppd-device-id", num_options, options);
+ language = cupsGetOption("ppd-natural-language", num_options, options);
+ make = cupsGetOption("ppd-make", num_options, options);
+ make_and_model = cupsGetOption("ppd-make-and-model", num_options, options);
+ product = cupsGetOption("ppd-product", num_options, options);
+ psversion = cupsGetOption("ppd-psversion", num_options, options);
+
+ if (make_and_model)
+ mam_len = strlen(make_and_model);
+ else
+ mam_len = 0;
- fprintf(stderr, "DEBUG: [cups-driverd] requested=\"%s\"\n",
- requested ? requested : "(nil)");
+ if (device_id)
+ device_id_len = strlen(device_id);
+ else
+ device_id_len = 0;
+
+ if (requested)
+ fprintf(stderr, "DEBUG: [cups-driverd] requested-attributes=\"%s\"\n",
+ requested);
+ if (device_id)
+ fprintf(stderr, "DEBUG: [cups-driverd] ppd-device-id=\"%s\"\n",
+ device_id);
+ if (language)
+ fprintf(stderr, "DEBUG: [cups-driverd] ppd-natural-language=\"%s\"\n",
+ language);
+ if (make)
+ fprintf(stderr, "DEBUG: [cups-driverd] ppd-make=\"%s\"\n",
+ make);
+ if (make_and_model)
+ fprintf(stderr, "DEBUG: [cups-driverd] ppd-make-and-model=\"%s\"\n",
+ make_and_model);
+ if (product)
+ fprintf(stderr, "DEBUG: [cups-driverd] ppd-product=\"%s\"\n",
+ product);
+ if (psversion)
+ fprintf(stderr, "DEBUG: [cups-driverd] ppd-psversion=\"%s\"\n",
+ psversion);
if (!requested || strstr(requested, "all"))
{
@@ -567,6 +797,7 @@ list_ppds(int request_id, /* I - Request ID */
send_natural_language = 1;
send_device_id = 1;
send_product = 1;
+ send_psversion = 1;
}
else
{
@@ -578,14 +809,12 @@ list_ppds(int request_id, /* I - Request ID */
send_natural_language = strstr(requested, "ppd-natural-language") != NULL;
send_device_id = strstr(requested, "ppd-device-id") != NULL;
send_product = strstr(requested, "ppd-product") != NULL;
+ send_psversion = strstr(requested, "ppd-psversion") != NULL;
}
puts("Content-Type: application/ipp\n");
- cupsdSendIPPHeader(IPP_OK, request_id);
- cupsdSendIPPGroup(IPP_TAG_OPERATION);
- cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
- cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", "en-US");
+ sent_header = 0;
if (limit <= 0 || limit > NumPPDs)
count = NumPPDs;
@@ -593,59 +822,143 @@ list_ppds(int request_id, /* I - Request ID */
count = limit;
for (i = NumPPDs, ppd = PPDs; count > 0 && i > 0; i --, ppd ++)
- if (!make || !strcasecmp(ppd->record.make, make))
+ {
+ /*
+ * Filter PPDs based on make, model, or device ID...
+ */
+
+ if (device_id && strncasecmp(ppd->record.device_id, device_id,
+ device_id_len))
+ continue; /* TODO: implement smart compare */
+
+ if (language)
{
- /*
- * Send this PPD...
- */
+ for (j = 0; j < PPD_MAX_LANG; j ++)
+ if (!ppd->record.languages[j][0] ||
+ !strcasecmp(ppd->record.languages[j], language))
+ break;
+
+ if (j >= PPD_MAX_LANG || !ppd->record.languages[j][0])
+ continue;
+ }
+
+ if (make && strcasecmp(ppd->record.make, make))
+ continue;
+
+ if (make_and_model && strncasecmp(ppd->record.make_and_model,
+ make_and_model, mam_len))
+ continue;
+
+ if (product)
+ {
+ for (j = 0; j < PPD_MAX_PROD; j ++)
+ if (!ppd->record.products[j][0] ||
+ !strcasecmp(ppd->record.products[j], product))
+ break;
- fprintf(stderr, "DEBUG: [cups-driverd] Sending %s (%s)...\n",
- ppd->record.name, ppd->record.make_and_model);
+ if (j >= PPD_MAX_PROD || !ppd->record.products[j][0])
+ continue;
+ }
- count --;
+ if (psversion)
+ {
+ for (j = 0; j < PPD_MAX_VERS; j ++)
+ if (!ppd->record.psversions[j][0] ||
+ !strcasecmp(ppd->record.psversions[j], psversion))
+ break;
- cupsdSendIPPGroup(IPP_TAG_PRINTER);
+ if (j >= PPD_MAX_VERS || !ppd->record.psversions[j][0])
+ continue;
+ }
- if (send_name)
- cupsdSendIPPString(IPP_TAG_NAME, "ppd-name", ppd->record.name);
+ /*
+ * Send this PPD...
+ */
- if (send_natural_language)
- cupsdSendIPPString(IPP_TAG_LANGUAGE, "ppd-natural-language",
- ppd->record.natural_language);
+ if (!sent_header)
+ {
+ sent_header = 1;
- if (send_make)
- cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make", ppd->record.make);
+ cupsdSendIPPHeader(IPP_OK, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", "en-US");
+ }
- if (send_make_and_model)
- cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make-and-model",
- ppd->record.make_and_model);
+ fprintf(stderr, "DEBUG: [cups-driverd] Sending %s (%s)...\n",
+ ppd->record.name, ppd->record.make_and_model);
- if (send_device_id)
- cupsdSendIPPString(IPP_TAG_TEXT, "ppd-device-id",
- ppd->record.device_id);
+ count --;
- if (send_product)
- cupsdSendIPPString(IPP_TAG_TEXT, "ppd-product",
- ppd->record.product);
+ cupsdSendIPPGroup(IPP_TAG_PRINTER);
- /*
- * If we have only requested the ppd-make attribute, then skip
- * the remaining PPDs with this make...
- */
+ if (send_name)
+ cupsdSendIPPString(IPP_TAG_NAME, "ppd-name", ppd->record.name);
- if (requested && !strcmp(requested, "ppd-make"))
- {
- const char *this_make; /* This ppd-make */
+ if (send_natural_language)
+ {
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "ppd-natural-language",
+ ppd->record.languages[0]);
+ for (j = 1; j < PPD_MAX_LANG && ppd->record.languages[j][0]; j ++)
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "", ppd->record.languages[j]);
+ }
- for (this_make = ppd->record.make, i --, ppd ++; i > 0; i --, ppd ++)
- if (strcasecmp(this_make, ppd->record.make))
- break;
+ if (send_make)
+ cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make", ppd->record.make);
- i ++;
- ppd --;
- }
+ if (send_make_and_model)
+ cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make-and-model",
+ ppd->record.make_and_model);
+
+ if (send_device_id)
+ cupsdSendIPPString(IPP_TAG_TEXT, "ppd-device-id",
+ ppd->record.device_id);
+
+ if (send_product)
+ {
+ cupsdSendIPPString(IPP_TAG_TEXT, "ppd-product",
+ ppd->record.products[0]);
+
+ for (j = 1; j < PPD_MAX_PROD && ppd->record.products[j][0]; j ++)
+ cupsdSendIPPString(IPP_TAG_TEXT, "", ppd->record.products[j]);
+ }
+
+ if (send_psversion)
+ {
+ cupsdSendIPPString(IPP_TAG_TEXT, "ppd-psversion",
+ ppd->record.psversions[0]);
+
+ for (j = 1; j < PPD_MAX_VERS && ppd->record.psversions[j][0]; j ++)
+ cupsdSendIPPString(IPP_TAG_TEXT, "", ppd->record.psversions[j]);
+ }
+
+ /*
+ * If we have only requested the ppd-make attribute, then skip
+ * the remaining PPDs with this make...
+ */
+
+ if (requested && !strcmp(requested, "ppd-make"))
+ {
+ const char *this_make; /* This ppd-make */
+
+
+ for (this_make = ppd->record.make, i --, ppd ++; i > 0; i --, ppd ++)
+ if (strcasecmp(this_make, ppd->record.make))
+ break;
+
+ i ++;
+ ppd --;
}
+ }
+
+ if (!sent_header)
+ {
+ cupsdSendIPPHeader(IPP_NOT_FOUND, request_id);
+ cupsdSendIPPGroup(IPP_TAG_OPERATION);
+ cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8");
+ cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", "en-US");
+ }
cupsdSendIPPTrailer();
@@ -659,7 +972,8 @@ list_ppds(int request_id, /* I - Request ID */
static int /* O - 1 on success, 0 on failure */
load_ppds(const char *d, /* I - Actual directory */
- const char *p) /* I - Virtual path in name */
+ const char *p, /* I - Virtual path in name */
+ int descend) /* I - Descend into directories? */
{
int i; /* Looping var */
cups_file_t *fp; /* Pointer to file */
@@ -677,8 +991,11 @@ load_ppds(const char *d, /* I - Actual directory */
model_name[256], /* ModelName */
nick_name[256], /* NickName */
device_id[256], /* 1284DeviceID */
- product[256]; /* Product */
- cups_array_t *products; /* Array of product strings */
+ product[256], /* Product */
+ psversion[256]; /* PSVersion */
+ cups_array_t *products, /* Product array */
+ *psversions, /* PSVersion array */
+ *cups_languages; /* cupsLanguages array */
ppd_info_t *ppd, /* New PPD file */
key; /* Search key */
int new_ppd; /* Is this a new PPD? */
@@ -688,7 +1005,7 @@ load_ppds(const char *d, /* I - Actual directory */
*language; /* Language code */
} languages[] =
{
- { "chinese", "cn" },
+ { "chinese", "zh" },
{ "danish", "da" },
{ "dutch", "nl" },
{ "english", "en" },
@@ -711,7 +1028,8 @@ load_ppds(const char *d, /* I - Actual directory */
if ((dir = cupsDirOpen(d)) == NULL)
{
- fprintf(stderr, "ERROR: [cups-driverd] Unable to open PPD directory \"%s\": %s\n",
+ fprintf(stderr,
+ "ERROR: [cups-driverd] Unable to open PPD directory \"%s\": %s\n",
d, strerror(errno));
return (0);
}
@@ -742,11 +1060,12 @@ load_ppds(const char *d, /* I - Actual directory */
* Do subdirectory...
*/
- if (!load_ppds(filename, name))
- {
- cupsDirClose(dir);
- return (1);
- }
+ if (descend)
+ if (!load_ppds(filename, name, 1))
+ {
+ cupsDirClose(dir);
+ return (1);
+ }
continue;
}
@@ -802,7 +1121,9 @@ load_ppds(const char *d, /* I - Actual directory */
* Now read until we get the NickName field...
*/
- products = cupsArrayNew(NULL, NULL);
+ cups_languages = cupsArrayNew(NULL, NULL);
+ products = cupsArrayNew(NULL, NULL);
+ psversions = cupsArrayNew(NULL, NULL);
model_name[0] = '\0';
nick_name[0] = '\0';
@@ -830,6 +1151,39 @@ load_ppds(const char *d, /* I - Actual directory */
sscanf(line, "%*[^\"]\"(%255[^)]", product);
cupsArrayAdd(products, strdup(product));
}
+ else if (!strncasecmp(line, "*PSVersion:", 11))
+ {
+ sscanf(line, "%*[^\"]\"%255[^\"]", psversion);
+ cupsArrayAdd(psversions, strdup(psversion));
+ }
+ else if (!strncasecmp(line, "*cupsLanguages:", 15))
+ {
+ char *start; /* Start of language */
+
+
+ for (start = line + 15; *start && isspace(*start & 255); start ++);
+
+ if (*start++ == '\"')
+ {
+ while (*start)
+ {
+ for (ptr = start + 1;
+ *ptr && *ptr != '\"' && !isspace(*ptr & 255);
+ ptr ++);
+
+ if (*ptr)
+ {
+ *ptr++ = '\0';
+
+ while (isspace(*ptr & 255))
+ *ptr++ = '\0';
+ }
+
+ cupsArrayAdd(cups_languages, strdup(start));
+ start = ptr;
+ }
+ }
+ }
else if (!strncmp(line, "*OpenUI", 7))
{
/*
@@ -837,7 +1191,8 @@ load_ppds(const char *d, /* I - Actual directory */
* before the first OpenUI...
*/
- if ((model_name[0] || nick_name[0]) && cupsArrayCount(products) > 0)
+ if ((model_name[0] || nick_name[0]) && cupsArrayCount(products) > 0 &&
+ cupsArrayCount(psversions) > 0)
break;
}
}
@@ -861,7 +1216,8 @@ load_ppds(const char *d, /* I - Actual directory */
while (isspace(make_model[0] & 255))
_cups_strcpy(make_model, make_model + 1);
- if (!make_model[0] || cupsArrayCount(products) == 0)
+ if (!make_model[0] || cupsArrayCount(products) == 0 ||
+ cupsArrayCount(psversions) == 0)
{
/*
* We don't have all the info needed, so skip this file...
@@ -874,12 +1230,12 @@ load_ppds(const char *d, /* I - Actual directory */
if (cupsArrayCount(products) == 0)
fprintf(stderr, "WARNING: Missing Product in %s!\n", filename);
- for (ptr = (char *)cupsArrayFirst(products);
- ptr;
- ptr = (char *)cupsArrayNext(products))
- free(ptr);
+ if (cupsArrayCount(psversions) == 0)
+ fprintf(stderr, "WARNING: Missing PSVersion in %s!\n", filename);
- cupsArrayDelete(products);
+ free_array(products);
+ free_array(psversions);
+ free_array(cups_languages);
continue;
}
@@ -1007,10 +1363,12 @@ load_ppds(const char *d, /* I - Actual directory */
fprintf(stderr, "DEBUG: [cups-driverd] Adding ppd \"%s\"...\n", name);
- /* TODO: Support multiple Products... */
- if (!add_ppd(name, lang_version, manufacturer, make_model, device_id,
- (char *)cupsArrayFirst(products),
- dent->fileinfo.st_mtime, dent->fileinfo.st_size))
+ ppd = add_ppd(name, lang_version, manufacturer, make_model, device_id,
+ (char *)cupsArrayFirst(products),
+ (char *)cupsArrayFirst(psversions),
+ dent->fileinfo.st_mtime, dent->fileinfo.st_size);
+
+ if (!ppd)
{
cupsDirClose(dir);
return (0);
@@ -1034,23 +1392,44 @@ load_ppds(const char *d, /* I - Actual directory */
strlcpy(ppd->record.make, manufacturer, sizeof(ppd->record.make));
strlcpy(ppd->record.make_and_model, make_model,
sizeof(ppd->record.make_and_model));
- strlcpy(ppd->record.natural_language, lang_version,
- sizeof(ppd->record.natural_language));
- strlcpy(ppd->record.product, (char *)cupsArrayFirst(products),
- sizeof(ppd->record.product));
+ strlcpy(ppd->record.languages[0], lang_version,
+ sizeof(ppd->record.languages[0]));
+ strlcpy(ppd->record.products[0], (char *)cupsArrayFirst(products),
+ sizeof(ppd->record.products[0]));
+ strlcpy(ppd->record.psversions[0], (char *)cupsArrayFirst(psversions),
+ sizeof(ppd->record.psversions[0]));
strlcpy(ppd->record.device_id, device_id, sizeof(ppd->record.device_id));
}
/*
- * Free products...
+ * Add remaining products, versions, and languages...
*/
- for (ptr = (char *)cupsArrayFirst(products);
- ptr;
- ptr = (char *)cupsArrayNext(products))
- free(ptr);
+ for (i = 1;
+ i < PPD_MAX_PROD && (ptr = (char *)cupsArrayNext(products)) != NULL;
+ i ++)
+ strlcpy(ppd->record.products[i], ptr,
+ sizeof(ppd->record.products[0]));
+
+ for (i = 1;
+ i < PPD_MAX_VERS && (ptr = (char *)cupsArrayNext(psversions)) != NULL;
+ i ++)
+ strlcpy(ppd->record.psversions[i], ptr,
+ sizeof(ppd->record.psversions[0]));
- cupsArrayDelete(products);
+ for (i = 1, ptr = (char *)cupsArrayFirst(cups_languages);
+ i < PPD_MAX_LANG && ptr;
+ i ++, ptr = (char *)cupsArrayNext(cups_languages))
+ strlcpy(ppd->record.languages[i], ptr,
+ sizeof(ppd->record.languages[0]));
+
+ /*
+ * Free products, versions, and languages...
+ */
+
+ free_array(cups_languages);
+ free_array(products);
+ free_array(psversions);
ChangedPPD = 1;
}
@@ -1068,7 +1447,10 @@ load_ppds(const char *d, /* I - Actual directory */
static int /* O - 1 on success, 0 on failure */
load_drivers(void)
{
- const char *server_bin; /* CUPS_SERVERBIN environment variable */
+ int i; /* Looping var */
+ char *start, /* Start of value */
+ *ptr; /* Pointer into string */
+ const char *server_bin; /* CUPS_SERVERBIN env variable */
char drivers[1024]; /* Location of driver programs */
FILE *fp; /* Pipe to driver program */
cups_dir_t *dir; /* Directory pointer */
@@ -1076,11 +1458,13 @@ load_drivers(void)
char filename[1024], /* Name of driver */
line[2048], /* Line from driver */
name[512], /* ppd-name */
- natural_language[128], /* ppd-natural-language */
make[128], /* ppd-make */
- make_and_model[256], /* ppd-make-and-model */
- device_id[256], /* ppd-device-id */
- product[256]; /* ppd-product */
+ make_and_model[128], /* ppd-make-and-model */
+ device_id[128], /* ppd-device-id */
+ languages[128], /* ppd-natural-language */
+ product[128], /* ppd-product */
+ psversion[128]; /* ppd-psversion */
+ ppd_info_t *ppd; /* Newly added PPD */
/*
@@ -1126,17 +1510,18 @@ load_drivers(void)
* Each line is of the form:
*
* "ppd-name" ppd-natural-language "ppd-make" "ppd-make-and-model" \
- * "ppd-device-id" "ppd-product"
+ * "ppd-device-id" "ppd-product" "ppd-psversion"
*/
device_id[0] = '\0';
product[0] = '\0';
+ psversion[0] = '\0';
if (sscanf(line, "\"%511[^\"]\"%127s%*[ \t]\"%127[^\"]\""
- "%*[ \t]\"%256[^\"]\"%*[ \t]\"%256[^\"]\""
- "%*[ \t]\"%256[^\"]\"",
- name, natural_language, make, make_and_model,
- device_id, product) < 4)
+ "%*[ \t]\"%127[^\"]\"%*[ \t]\"%127[^\"]\""
+ "%*[ \t]\"%127[^\"]\"%*[ \t]\"%127[^\"]\"",
+ name, languages, make, make_and_model,
+ device_id, product, psversion) < 4)
{
/*
* Bad format; strip trailing newline and write an error message.
@@ -1155,13 +1540,34 @@ load_drivers(void)
* Add the device to the array of available devices...
*/
- if (!add_ppd(name, natural_language, make, make_and_model, device_id,
- product, 0, 0))
+ if ((start = strchr(languages, ',')) != NULL)
+ *start++ = '\0';
+
+ ppd = add_ppd(name, languages, make, make_and_model, device_id,
+ product, psversion, 0, 0);
+
+ if (!ppd)
{
cupsDirClose(dir);
return (0);
}
+ if (start && *start)
+ {
+ for (i = 1; i < PPD_MAX_LANG && *start; i ++)
+ {
+ if ((ptr = strchr(start, ',')) != NULL)
+ *ptr++ = '\0';
+ else
+ ptr = start + strlen(start);
+
+ strlcpy(ppd->record.languages[i], start,
+ sizeof(ppd->record.languages[0]));
+
+ start = ptr;
+ }
+ }
+
fprintf(stderr, "DEBUG: [cups-driverd] Added dynamic PPD \"%s\"...\n",
name);
}
@@ -1181,5 +1587,5 @@ load_drivers(void)
/*
- * End of "$Id: cups-driverd.c 6377 2007-03-21 07:17:11Z mike $".
+ * End of "$Id: cups-driverd.c 6508 2007-05-03 20:07:14Z mike $".
*/
diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c
index 2ae4b6805..373b7c535 100644
--- a/scheduler/dirsvc.c
+++ b/scheduler/dirsvc.c
@@ -1,5 +1,5 @@
/*
- * "$Id: dirsvc.c 6376 2007-03-21 06:39:10Z mike $"
+ * "$Id: dirsvc.c 6483 2007-04-30 17:16:16Z mike $"
*
* Directory services routines for the Common UNIX Printing System (CUPS).
*
@@ -2931,7 +2931,7 @@ send_cups_browse(cupsd_printer_t *p) /* I - Printer to send */
{
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
iface->hostname, iface->port,
- (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s%s" :
+ (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s" :
"/printers/%s",
p->name);
snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s\n",
@@ -3802,5 +3802,5 @@ update_polling(void)
/*
- * End of "$Id: dirsvc.c 6376 2007-03-21 06:39:10Z mike $".
+ * End of "$Id: dirsvc.c 6483 2007-04-30 17:16:16Z mike $".
*/
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index 5a8555ac4..bbba01621 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -1,5 +1,5 @@
/*
- * "$Id: ipp.c 6433 2007-04-02 21:50:50Z mike $"
+ * "$Id: ipp.c 6508 2007-05-03 20:07:14Z mike $"
*
* IPP routines for the Common UNIX Printing System (CUPS) scheduler.
*
@@ -65,6 +65,7 @@
* get_job_attrs() - Get job attributes.
* get_jobs() - Get a list of jobs for the specified printer.
* get_notifications() - Get events for a subscription.
+ * get_ppd() - Get a named PPD from the local system.
* get_ppds() - Get the list of PPD files on the local
* system.
* get_printer_attrs() - Get printer attributes.
@@ -92,6 +93,7 @@
* start_printer() - Start a printer.
* stop_printer() - Stop a printer.
* url_encode_attr() - URL-encode a string attribute.
+ * url_encode_string() - URL-encode a string.
* user_allowed() - See if a user is allowed to print to a queue.
* validate_job() - Validate printer options and destination.
* validate_name() - Make sure the printer name only contains
@@ -178,6 +180,7 @@ static void get_devices(cupsd_client_t *con);
static void get_jobs(cupsd_client_t *con, ipp_attribute_t *uri);
static void get_job_attrs(cupsd_client_t *con, ipp_attribute_t *uri);
static void get_notifications(cupsd_client_t *con);
+static void get_ppd(cupsd_client_t *con, ipp_attribute_t *uri);
static void get_ppds(cupsd_client_t *con);
static void get_printers(cupsd_client_t *con, int type);
static void get_printer_attrs(cupsd_client_t *con, ipp_attribute_t *uri);
@@ -216,6 +219,7 @@ static void start_printer(cupsd_client_t *con, ipp_attribute_t *uri);
static void stop_printer(cupsd_client_t *con, ipp_attribute_t *uri);
static void url_encode_attr(ipp_attribute_t *attr, char *buffer,
int bufsize);
+static char *url_encode_string(const char *s, char *buffer, int bufsize);
static int user_allowed(cupsd_printer_t *p, const char *username);
static void validate_job(cupsd_client_t *con, ipp_attribute_t *uri);
static int validate_name(const char *name);
@@ -344,6 +348,8 @@ cupsdProcessIPPRequest(
else if ((attr = ippFindAttribute(con->request, "job-uri",
IPP_TAG_URI)) != NULL)
uri = attr;
+ else if (con->request->request.op.operation_id == CUPS_GET_PPD)
+ uri = ippFindAttribute(con->request, "ppd-name", IPP_TAG_NAME);
else
uri = NULL;
@@ -399,11 +405,12 @@ cupsdProcessIPPRequest(
if (!uri)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "Missing printer-uri or job-uri attribute!");
+ "Missing printer-uri, job-uri, or ppd-name "
+ "attribute!");
cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL,
- "%04X %s Missing printer-uri or job-uri attribute",
- IPP_BAD_REQUEST, con->http.hostname);
+ "%04X %s Missing printer-uri, job-uri, or ppd-name "
+ "attribute", IPP_BAD_REQUEST, con->http.hostname);
}
cupsdLogMessage(CUPSD_LOG_DEBUG, "Request attributes follow...");
@@ -572,6 +579,10 @@ cupsdProcessIPPRequest(
get_devices(con);
break;
+ case CUPS_GET_PPD :
+ get_ppd(con, uri);
+ break;
+
case CUPS_GET_PPDS :
get_ppds(con);
break;
@@ -665,6 +676,15 @@ cupsdProcessIPPRequest(
length = ippLength(con->response);
+ if (con->file >= 0 && !con->pipe_pid)
+ {
+ struct stat fileinfo; /* File information */
+
+
+ if (!fstat(con->file, &fileinfo))
+ length += fileinfo.st_size;
+ }
+
if (httpPrintf(HTTP(con), "Content-Length: " CUPS_LLFMT "\r\n\r\n",
CUPS_LLCAST length) < 0)
return (0);
@@ -674,6 +694,11 @@ cupsdProcessIPPRequest(
con->http.data_encoding = HTTP_ENCODE_LENGTH;
con->http.data_remaining = length;
+
+ if (con->http.data_remaining <= INT_MAX)
+ con->http._data_remaining = con->http.data_remaining;
+ else
+ con->http._data_remaining = INT_MAX;
}
cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient,
@@ -5888,6 +5913,147 @@ get_notifications(cupsd_client_t *con) /* I - Client connection */
/*
+ * 'get_ppd()' - Get a named PPD from the local system.
+ */
+
+static void
+get_ppd(cupsd_client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI or PPD name */
+{
+ http_status_t status; /* Policy status */
+ cupsd_printer_t *dest; /* Destination */
+ cups_ptype_t dtype; /* Destination type */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppd(%p[%d], %p[%s=%s])", con,
+ con->http.fd, uri, uri->name, uri->values[0].string.text);
+
+ if (!strcmp(uri->name, "ppd-name"))
+ {
+ /*
+ * Return a PPD file from cups-driverd...
+ */
+
+ char command[1024], /* cups-driverd command */
+ options[1024], /* Options to pass to command */
+ ppd_name[1024]; /* ppd-name */
+
+
+ /*
+ * Check policy...
+ */
+
+ if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
+ {
+ send_http_error(con, status, NULL);
+ return;
+ }
+
+ /*
+ * Run cups-driverd command with the given options...
+ */
+
+ snprintf(command, sizeof(command), "%s/daemon/cups-driverd", ServerBin);
+ url_encode_string(uri->values[0].string.text, ppd_name, sizeof(ppd_name));
+ snprintf(options, sizeof(options), "get+%d+%s",
+ con->request->request.op.request_id, ppd_name);
+
+ if (cupsdSendCommand(con, command, options, 0))
+ {
+ /*
+ * Command started successfully, don't send an IPP response here...
+ */
+
+ ippDelete(con->response);
+ con->response = NULL;
+ }
+ else
+ {
+ /*
+ * Command failed, return "internal error" so the user knows something
+ * went wrong...
+ */
+
+ send_ipp_status(con, IPP_INTERNAL_ERROR,
+ _("cups-driverd failed to execute."));
+ }
+ }
+ else if (!strcmp(uri->name, "printer-uri") &&
+ cupsdValidateDest(uri->values[0].string.text, &dtype, &dest))
+ {
+ int i; /* Looping var */
+ char filename[1024]; /* PPD filename */
+
+
+ /*
+ * Check policy...
+ */
+
+ if ((status = cupsdCheckPolicy(dest->op_policy_ptr, con, NULL)) != HTTP_OK)
+ {
+ send_http_error(con, status, NULL);
+ return;
+ }
+
+ /*
+ * See if we need the PPD for a class or remote printer...
+ */
+
+ if (dtype & CUPS_PRINTER_REMOTE)
+ {
+ send_ipp_status(con, CUPS_SEE_OTHER, NULL);
+ ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, dest->uri);
+ return;
+ }
+ else if (dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))
+ {
+ for (i = 0; i < dest->num_printers; i ++)
+ if (!(dest->printers[i]->type &
+ (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
+ CUPS_PRINTER_REMOTE)))
+ break;
+
+ if (i < dest->num_printers)
+ dest = dest->printers[i];
+ else
+ {
+ send_ipp_status(con, CUPS_SEE_OTHER, NULL);
+ ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, dest->printers[0]->uri);
+ return;
+ }
+ }
+
+ /*
+ * Found the printer with the PPD file, now see if there is one...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot,
+ dest->name);
+
+ if ((con->file = open(filename, O_RDONLY)) < 0)
+ {
+ send_ipp_status(con, IPP_NOT_FOUND,
+ _("The PPD file \"%s\" could not be opened: %s"),
+ uri->values[i].string.text, strerror(errno));
+ return;
+ }
+
+ fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC);
+
+ con->pipe_pid = 0;
+
+ send_ipp_status(con, IPP_OK, NULL);
+ }
+ else
+ send_ipp_status(con, IPP_NOT_FOUND,
+ _("The PPD file \"%s\" could not be found."),
+ uri->values[0].string.text);
+}
+
+
+/*
* 'get_ppds()' - Get the list of PPD files on the local system.
*/
@@ -5896,13 +6062,26 @@ get_ppds(cupsd_client_t *con) /* I - Client connection */
{
http_status_t status; /* Policy status */
ipp_attribute_t *limit, /* Limit attribute */
+ *device, /* ppd-device-id attribute */
+ *language, /* ppd-natural-language attribute */
*make, /* ppd-make attribute */
+ *model, /* ppd-make-and-model attribute */
+ *product, /* ppd-product attribute */
+ *psversion, /* ppd-psverion attribute */
*requested; /* requested-attributes attribute */
- char command[1024], /* cups-deviced command */
+ char command[1024], /* cups-driverd command */
options[1024], /* Options to pass to command */
- requested_str[256],
+ device_str[256],/* Escaped ppd-device-id string */
+ language_str[256],
+ /* Escaped ppd-natural-language string */
+ make_str[256], /* Escaped ppd-make string */
+ model_str[256], /* Escaped ppd-make-and-model string */
+ product_str[256],
+ /* Escaped ppd-product string */
+ psversion_str[256],
+ /* Escaped ppd-psversion string */
+ requested_str[256];
/* String for requested attributes */
- make_str[256]; /* Escaped ppd-make string */
cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppds(%p[%d])", con, con->http.fd);
@@ -5922,7 +6101,14 @@ get_ppds(cupsd_client_t *con) /* I - Client connection */
*/
limit = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER);
+ device = ippFindAttribute(con->request, "ppd-device-id", IPP_TAG_TEXT);
+ language = ippFindAttribute(con->request, "ppd-natural-language",
+ IPP_TAG_LANGUAGE);
make = ippFindAttribute(con->request, "ppd-make", IPP_TAG_TEXT);
+ model = ippFindAttribute(con->request, "ppd-make-and-model",
+ IPP_TAG_TEXT);
+ product = ippFindAttribute(con->request, "ppd-product", IPP_TAG_TEXT);
+ psversion = ippFindAttribute(con->request, "ppd-psversion", IPP_TAG_TEXT);
requested = ippFindAttribute(con->request, "requested-attributes",
IPP_TAG_KEYWORD);
@@ -5931,16 +6117,47 @@ get_ppds(cupsd_client_t *con) /* I - Client connection */
else
strlcpy(requested_str, "requested-attributes=all", sizeof(requested_str));
+ if (device)
+ url_encode_attr(device, device_str, sizeof(device_str));
+ else
+ device_str[0] = '\0';
+
+ if (language)
+ url_encode_attr(language, language_str, sizeof(language_str));
+ else
+ language_str[0] = '\0';
+
if (make)
url_encode_attr(make, make_str, sizeof(make_str));
else
make_str[0] = '\0';
+ if (model)
+ url_encode_attr(model, model_str, sizeof(model_str));
+ else
+ model_str[0] = '\0';
+
+ if (product)
+ url_encode_attr(product, product_str, sizeof(product_str));
+ else
+ product_str[0] = '\0';
+
+ if (psversion)
+ url_encode_attr(psversion, psversion_str, sizeof(psversion_str));
+ else
+ psversion_str[0] = '\0';
+
snprintf(command, sizeof(command), "%s/daemon/cups-driverd", ServerBin);
- snprintf(options, sizeof(options), "list+%d+%d+%s%s%s",
+ snprintf(options, sizeof(options), "list+%d+%d+%s%s%s%s%s%s%s%s%s%s%s%s%s",
con->request->request.op.request_id,
limit ? limit->values[0].integer : 0,
- requested_str, make ? "%20" : "", make_str);
+ requested_str,
+ device ? "%20" : "", device_str,
+ language ? "%20" : "", language_str,
+ make ? "%20" : "", make_str,
+ model ? "%20" : "", model_str,
+ product ? "%20" : "", product_str,
+ psversion ? "%20" : "", psversion_str);
if (cupsdSendCommand(con, command, options, 0))
{
@@ -7621,6 +7838,9 @@ renew_subscription(
cupsdSaveAllSubscriptions();
con->response->request.status.status_code = IPP_OK;
+
+ ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
+ "notify-lease-duration", sub->lease);
}
@@ -9221,8 +9441,7 @@ url_encode_attr(ipp_attribute_t *attr, /* I - Attribute */
{
int i; /* Looping var */
char *bufptr, /* Pointer into buffer */
- *bufend, /* End of buffer */
- *valptr; /* Pointer into value */
+ *bufend; /* End of buffer */
strlcpy(buffer, attr->name, bufsize);
@@ -9244,25 +9463,8 @@ url_encode_attr(ipp_attribute_t *attr, /* I - Attribute */
*bufptr++ = '\'';
- for (valptr = attr->values[i].string.text;
- *valptr && bufptr < bufend;
- valptr ++)
- if (*valptr == ' ')
- {
- if (bufptr >= (bufend - 2))
- break;
-
- *bufptr++ = '%';
- *bufptr++ = '2';
- *bufptr++ = '0';
- }
- else if (*valptr == '\'' || *valptr == '\\')
- {
- *bufptr++ = '\\';
- *bufptr++ = *valptr;
- }
- else
- *bufptr++ = *valptr;
+ bufptr = url_encode_string(attr->values[i].string.text,
+ bufptr, bufend - bufptr + 1);
if (bufptr >= bufend)
break;
@@ -9275,6 +9477,55 @@ url_encode_attr(ipp_attribute_t *attr, /* I - Attribute */
/*
+ * 'url_encode_string()' - URL-encode a string.
+ */
+
+static char * /* O - End of string */
+url_encode_string(const char *s, /* I - String */
+ char *buffer, /* I - String buffer */
+ int bufsize) /* I - Size of buffer */
+{
+ char *bufptr, /* Pointer into buffer */
+ *bufend; /* End of buffer */
+ static const char *hex = "0123456789ABCDEF";
+ /* Hex digits */
+
+
+ bufptr = buffer;
+ bufend = buffer + bufsize - 1;
+
+ while (*s && bufptr < bufend)
+ {
+ if (*s == ' ' || *s == '%')
+ {
+ if (bufptr >= (bufend - 2))
+ break;
+
+ *bufptr++ = '%';
+ *bufptr++ = hex[(*s >> 4) & 15];
+ *bufptr++ = hex[*s & 15];
+
+ s ++;
+ }
+ else if (*s == '\'' || *s == '\\')
+ {
+ if (bufptr >= (bufend - 1))
+ break;
+
+ *bufptr++ = '\\';
+ *bufptr++ = *s++;
+ }
+ else
+ *bufptr++ = *s++;
+ }
+
+ *bufptr = '\0';
+
+ return (bufptr);
+}
+
+
+/*
* 'user_allowed()' - See if a user is allowed to print to a queue.
*/
@@ -9485,5 +9736,5 @@ validate_user(cupsd_job_t *job, /* I - Job */
/*
- * End of "$Id: ipp.c 6433 2007-04-02 21:50:50Z mike $".
+ * End of "$Id: ipp.c 6508 2007-05-03 20:07:14Z mike $".
*/
diff --git a/scheduler/job.c b/scheduler/job.c
index 96513a2f5..90434af16 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -1,5 +1,5 @@
/*
- * "$Id: job.c 6433 2007-04-02 21:50:50Z mike $"
+ * "$Id: job.c 6462 2007-04-23 19:25:13Z mike $"
*
* Job management routines for the Common UNIX Printing System (CUPS).
*
@@ -2721,6 +2721,7 @@ start_job(cupsd_job_t *job, /* I - Job ID */
if ((!strcmp(attr->name, "page-label") ||
!strcmp(attr->name, "page-border") ||
!strncmp(attr->name, "number-up", 9) ||
+ !strcmp(attr->name, "page-ranges") ||
!strcmp(attr->name, "page-set") ||
!strcasecmp(attr->name, "AP_FIRSTPAGE_InputSlot") ||
!strcasecmp(attr->name, "AP_FIRSTPAGE_ManualFeed")) &&
@@ -3323,6 +3324,8 @@ start_job(cupsd_job_t *job, /* I - Job ID */
cupsdClosePipe(job->status_pipes);
cupsdStatBufDelete(job->status_buffer);
+ job->status_buffer = NULL;
+
cupsArrayDelete(filters);
if (printer->remote && job->num_files > 1)
@@ -3549,5 +3552,5 @@ update_job(cupsd_job_t *job) /* I - Job to check */
/*
- * End of "$Id: job.c 6433 2007-04-02 21:50:50Z mike $".
+ * End of "$Id: job.c 6462 2007-04-23 19:25:13Z mike $".
*/
diff --git a/scheduler/log.c b/scheduler/log.c
index 11c3cbcfe..2c7c573e2 100644
--- a/scheduler/log.c
+++ b/scheduler/log.c
@@ -1,9 +1,9 @@
/*
- * "$Id: log.c 6328 2007-03-12 14:45:42Z mike $"
+ * "$Id: log.c 6492 2007-04-30 19:31:36Z mike $"
*
* Log file routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
* property of Easy Software Products and are protected by Federal
@@ -546,10 +546,23 @@ check_log_file(cups_file_t **lf, /* IO - Log file */
if ((*lf = cupsFileOpen(filename, "a")) == NULL)
{
- syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename,
- strerror(errno));
+ /*
+ * If the file is in CUPS_LOGDIR then try to create a missing directory...
+ */
- return (0);
+ if (!strncmp(filename, CUPS_LOGDIR, strlen(CUPS_LOGDIR)))
+ {
+ cupsdCheckPermissions(CUPS_LOGDIR, NULL, 0755, RunUser, Group, 1, -1);
+
+ *lf = cupsFileOpen(filename, "a");
+ }
+
+ if (*lf == NULL)
+ {
+ syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename,
+ strerror(errno));
+ return (0);
+ }
}
if (strncmp(filename, "/dev/", 5))
@@ -603,5 +616,5 @@ check_log_file(cups_file_t **lf, /* IO - Log file */
/*
- * End of "$Id: log.c 6328 2007-03-12 14:45:42Z mike $".
+ * End of "$Id: log.c 6492 2007-04-30 19:31:36Z mike $".
*/
diff --git a/scheduler/main.c b/scheduler/main.c
index f17969eea..79d70912e 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -1,5 +1,5 @@
/*
- * "$Id: main.c 6365 2007-03-19 20:56:57Z mike $"
+ * "$Id: main.c 6493 2007-04-30 19:33:31Z mike $"
*
* Scheduler main loop for the Common UNIX Printing System (CUPS).
*
@@ -33,10 +33,6 @@
* launchd_checkin() - Check-in with launchd and collect the
* listening fds.
* launchd_checkout() - Check-out with launchd.
- * launchd_create_dict() - Create a dictionary representing the launchd
- * config file org.cups.cupsd.plist.
- * launchd_sync_conf() - Re-write the launchd config file
- * org.cups.cupsd.plist based on cupsd.conf.
* parent_handler() - Catch USR1/CHLD signals...
* process_children() - Process all dead children...
* sigchld_handler() - Handle 'child' signals from old processes.
@@ -93,8 +89,6 @@
#ifdef HAVE_LAUNCHD
static void launchd_checkin(void);
static void launchd_checkout(void);
-static CFDictionaryRef launchd_create_dict(void);
-static int launchd_sync_conf(void);
#endif /* HAVE_LAUNCHD */
static void parent_handler(int sig);
static void process_children(void);
@@ -120,13 +114,6 @@ static int dead_children = 0;
static int stop_scheduler = 0;
/* Should the scheduler stop? */
-#ifdef HAVE_LAUNCHD
-static CFURLRef launchd_conf_url = NULL;
- /* org.cups.cupsd.plist url */
-static CFDictionaryRef launchd_conf_dict = NULL;
- /* org.cups.cupsd.plist dict */
-#endif /* HAVE_LAUNCHD */
-
#if defined(__APPLE__) && defined(HAVE_DLFCN_H)
static const char *PSQLibPath = "/usr/lib/libPrintServiceQuota.dylib";
static const char *PSQLibFuncName = "PSQUpdateQuota";
@@ -366,7 +353,7 @@ main(int argc, /* I - Number of command-line args */
getrlimit(RLIMIT_NOFILE, &limit);
- for (i = 0; i < limit.rlim_cur; i ++)
+ for (i = 0; i < limit.rlim_cur && i < 1024; i ++)
close(i);
#endif /* DEBUG */
}
@@ -420,14 +407,7 @@ main(int argc, /* I - Number of command-line args */
if (Launchd)
{
/*
- * If we were started by launchd, make sure the cupsd plist file contains
- * the same listeners as cupsd.conf.
- */
-
- launchd_sync_conf();
-
- /*
- * Then get the file descriptors from launchd...
+ * If we were started by launchd get the listen sockets file descriptors...
*/
launchd_checkin();
@@ -638,7 +618,10 @@ main(int argc, /* I - Number of command-line args */
#if HAVE_LAUNCHD
if (Launchd)
{
- launchd_sync_conf();
+ /*
+ * If we were started by launchd get the listen sockets file descriptors...
+ */
+
launchd_checkin();
}
#endif /* HAVE_LAUNCHD */
@@ -952,21 +935,27 @@ main(int argc, /* I - Number of command-line args */
#ifdef HAVE_LAUNCHD
/*
- * Update the launchd config file as needed...
+ * Update the launchd KeepAlive file as needed...
*/
if (Launchd)
- {
launchd_checkout();
- launchd_sync_conf();
+#endif /* HAVE_LAUNCHD */
- if (launchd_conf_url)
- CFRelease(launchd_conf_url);
+#ifdef __APPLE__
+#ifdef HAVE_DLFCN_H
+ /*
+ * Unload Print Service quota enforcement library (X Server only)
+ */
- if (launchd_conf_dict)
- CFRelease(launchd_conf_dict);
+ PSQUpdateQuotaProc = NULL;
+ if (PSQLibRef)
+ {
+ dlclose(PSQLibRef);
+ PSQLibRef = NULL;
}
-#endif /* HAVE_LAUNCHD */
+#endif /* HAVE_DLFCN_H */
+#endif /* __APPLE__ */
#ifdef __sgi
/*
@@ -1335,38 +1324,6 @@ launchd_checkin(void)
}
}
- /*
- * Collect the browse socket (if there is one)...
- */
-
- if ((ld_array = launch_data_dict_lookup(ld_sockets, "BrowseSockets")))
- {
- if (launch_data_get_type(ld_array) == LAUNCH_DATA_ARRAY)
- {
- if ((tmp = launch_data_array_get_index(ld_array, 0)))
- {
- if (launch_data_get_type(tmp) == LAUNCH_DATA_FD)
- {
- if (BrowseSocket != -1)
- close(BrowseSocket);
-
- BrowseSocket = launch_data_get_fd(tmp);
- }
- else
- cupsdLogMessage(CUPSD_LOG_WARN,
- "launchd_checkin: BrowseSocket not a fd!");
- }
- else
- cupsdLogMessage(CUPSD_LOG_WARN,
- "launchd_checkin: BrowseSockets is an empty array!");
- }
- else
- cupsdLogMessage(CUPSD_LOG_WARN,
- "launchd_checkin: BrowseSockets is not an array!");
- }
- else
- cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: No BrowseSockets");
-
launch_data_free(ld_msg);
launch_data_free(ld_resp);
}
@@ -1408,340 +1365,6 @@ launchd_checkout(void)
}
}
-
-/*
- * 'launchd_create_dict()' - Create a dictionary representing the launchd
- * config file org.cups.cupsd.plist.
- */
-
-static CFDictionaryRef /* O - CFDictionary */
-launchd_create_dict(void)
-{
- int portnum; /* Port number */
- bool runatload; /* Run at load? */
- CFMutableDictionaryRef cupsd_dict, /* org.cups.cupsd.plist dictionary */
- keepalive, /* KeepAlive dictionary */
- pathstate, /* PathState dictionary */
- sockets, /* Sockets dictionary */
- listener; /* Listener dictionary */
- CFMutableArrayRef array; /* Array */
- CFNumberRef socket_mode; /* Domain socket mode bits */
- CFStringRef socket_path; /* Domain socket path */
- CFTypeRef value; /* CF values */
- cupsd_listener_t *lis; /* Current listening socket */
- struct servent *service; /* Services data base entry */
- char temp[1024]; /* Temporary buffer for value */
-
-
- if ((cupsd_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks)) == NULL)
- return (NULL);
-
- CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_LABEL),
- CFSTR("org.cups.cupsd"));
- CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_ONDEMAND),
- kCFBooleanTrue);
-
- /*
- * Use run-at-load and/or KeepAlive if there are active jobs, polling or
- * shared printers to advertise...
- */
-
- if ((keepalive = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks)) != NULL)
- {
- if ((pathstate = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks)) != NULL)
- {
- CFDictionaryAddValue(pathstate, CFSTR(CUPS_KEEPALIVE), kCFBooleanTrue);
- CFDictionaryAddValue(keepalive, CFSTR(LAUNCH_JOBKEY_PATHSTATE),
- pathstate);
- }
-
- CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_KEEPALIVE),
- keepalive);
- }
-
- runatload = (cupsArrayCount(ActiveJobs) || NumPolled ||
- (Browsing && BrowseLocalProtocols &&
- NumBrowsers && cupsArrayCount(Printers))) ? true : false;
-
- CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_RUNATLOAD),
- runatload ? kCFBooleanTrue : kCFBooleanFalse);
- CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_SERVICEIPC),
- kCFBooleanTrue);
-
- if ((array = CFArrayCreateMutable(kCFAllocatorDefault, 2,
- &kCFTypeArrayCallBacks)) != NULL)
- {
- CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_PROGRAMARGUMENTS),
- array);
- CFArrayAppendValue(array, CFSTR("/usr/sbin/cupsd"));
- CFArrayAppendValue(array, CFSTR("-l"));
- CFRelease(array);
- }
-
- /*
- * Add a sockets dictionary...
- */
-
- if ((sockets = (CFMutableDictionaryRef)CFDictionaryCreateMutable(
- kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks)) != NULL)
- {
- CFDictionaryAddValue(cupsd_dict, CFSTR(LAUNCH_JOBKEY_SOCKETS), sockets);
-
- /*
- * Add a Listeners array to the sockets dictionary...
- */
-
- if ((array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeArrayCallBacks)) != NULL)
- {
- CFDictionaryAddValue(sockets, CFSTR("Listeners"), array);
-
- /*
- * For each listener add a dictionary to the listeners array...
- */
-
- for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
- lis;
- lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
- {
- if ((listener = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks)) != NULL)
- {
- CFArrayAppendValue(array, listener);
-
-# ifdef AF_LOCAL
- if (lis->address.addr.sa_family == AF_LOCAL)
- {
- if ((socket_path = CFStringCreateWithCString(kCFAllocatorDefault,
- lis->address.un.sun_path,
- kCFStringEncodingUTF8)))
- {
- CFDictionaryAddValue(listener,
- CFSTR(LAUNCH_JOBSOCKETKEY_PATHNAME),
- socket_path);
- CFRelease(socket_path);
- }
- portnum = 0140777; /* (S_IFSOCK|S_IRWXU|S_IRWXG|S_IRWXO) or *
- * 49663d decimal */
- if ((socket_mode = CFNumberCreate(kCFAllocatorDefault,
- kCFNumberIntType, &portnum)))
- {
- CFDictionaryAddValue(listener, CFSTR("SockPathMode"),
- socket_mode);
- CFRelease(socket_mode);
- }
- }
- else
-# endif /* AF_LOCAL */
- {
-# ifdef AF_INET6
- if (lis->address.addr.sa_family == AF_INET6)
- {
- CFDictionaryAddValue(listener,
- CFSTR(LAUNCH_JOBSOCKETKEY_FAMILY),
- CFSTR("IPv6"));
- portnum = lis->address.ipv6.sin6_port;
- }
- else
-# endif /* AF_INET6 */
- {
- CFDictionaryAddValue(listener,
- CFSTR(LAUNCH_JOBSOCKETKEY_FAMILY),
- CFSTR("IPv4"));
- portnum = lis->address.ipv4.sin_port;
- }
-
- if ((service = getservbyport(portnum, NULL)))
- value = CFStringCreateWithCString(kCFAllocatorDefault,
- service->s_name,
- kCFStringEncodingUTF8);
- else
- value = CFNumberCreate(kCFAllocatorDefault,
- kCFNumberIntType, &portnum);
-
- if (value)
- {
- CFDictionaryAddValue(listener,
- CFSTR(LAUNCH_JOBSOCKETKEY_SERVICENAME),
- value);
- CFRelease(value);
- }
-
- httpAddrString(&lis->address, temp, sizeof(temp));
- if ((value = CFStringCreateWithCString(kCFAllocatorDefault, temp,
- kCFStringEncodingUTF8)))
- {
- CFDictionaryAddValue(listener,
- CFSTR(LAUNCH_JOBSOCKETKEY_NODENAME),
- value);
- CFRelease(value);
- }
- }
-
- CFRelease(listener);
- }
- }
-
- CFRelease(array);
- }
-
- /*
- * Add the BrowseSocket to the sockets dictionary...
- */
-
- if (Browsing && (BrowseRemoteProtocols & BROWSE_CUPS))
- {
- if ((array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeArrayCallBacks)) != NULL)
- {
- CFDictionaryAddValue(sockets, CFSTR("BrowseSockets"), array);
-
- if ((listener = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks)) != NULL)
- {
- CFArrayAppendValue(array, listener);
-
- CFDictionaryAddValue(listener, CFSTR(LAUNCH_JOBSOCKETKEY_FAMILY),
- CFSTR("IPv4"));
- CFDictionaryAddValue(listener, CFSTR(LAUNCH_JOBSOCKETKEY_TYPE),
- CFSTR("dgram"));
-
- if ((service = getservbyport(BrowsePort, NULL)))
- value = CFStringCreateWithCString(kCFAllocatorDefault,
- service->s_name,
- kCFStringEncodingUTF8);
- else
- value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType,
- &BrowsePort);
-
- CFDictionaryAddValue(listener,
- CFSTR(LAUNCH_JOBSOCKETKEY_SERVICENAME), value);
- CFRelease(value);
-
- CFRelease(listener);
- }
-
- CFRelease(array);
- }
- }
-
- CFRelease(sockets);
- }
-
- return (cupsd_dict);
-}
-
-
-/*
- * 'launchd_sync_conf()' - Rewrite the launchd config file
- * org.cups.cupsd.plist based on cupsd.conf.
- */
-
-static int /* O - 1 if the file was updated */
-launchd_sync_conf(void)
-{
- SInt32 errorCode; /* Error code */
- CFDataRef resourceData; /* XML property list */
- CFDictionaryRef cupsd_dict; /* New org.cups.cupsd.plist dict */
-
-
- /*
- * If needed reconstitute the existing org.cups.cupsd.plist...
- */
-
- if (!launchd_conf_url &&
- !(launchd_conf_url = CFURLCreateFromFileSystemRepresentation(
- kCFAllocatorDefault,
- (const unsigned char *)LaunchdConf,
- strlen(LaunchdConf), false)))
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_sync_conf: "
- "Unable to create file URL for \"%s\"\n", LaunchdConf);
- return (0);
- }
-
- if (!launchd_conf_dict)
- {
- if (CFURLCreateDataAndPropertiesFromResource(NULL, launchd_conf_url,
- &resourceData, NULL, NULL, &errorCode))
- {
- launchd_conf_dict = CFPropertyListCreateFromXMLData(NULL, resourceData,
- kCFPropertyListImmutable, NULL);
- CFRelease(resourceData);
- }
-
- if (!launchd_conf_dict)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_sync_conf: "
- "Unable to create dictionary for \"%s\"\n", LaunchdConf);
- }
- }
-
- /*
- * Create a new org.cups.cupsd.plist dictionary...
- */
-
- if ((cupsd_dict = launchd_create_dict()) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_sync_conf: "
- "Unable to create file URL for \"%s\"\n", LaunchdConf);
- return (0);
- }
-
- /*
- * If the dictionaries are different write a new org.cups.cupsd.plist...
- */
-
- if (!CFEqual(cupsd_dict, launchd_conf_dict))
- {
- if ((resourceData = CFPropertyListCreateXMLData(kCFAllocatorDefault,
- cupsd_dict)))
- {
- if (CFURLWriteDataAndPropertiesToResource(launchd_conf_url, resourceData,
- NULL, &errorCode))
- {
- /*
- * The new cupsd dictionary becomes the on-disk launchd dictionary...
- */
-
- if (launchd_conf_dict)
- CFRelease(launchd_conf_dict);
-
- launchd_conf_dict = cupsd_dict;
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_WARN,
- "launchd_sync_conf: "
- "CFURLWriteDataAndPropertiesToResource(\"%s\") "
- "failed: %d\n",
- LaunchdConf, (int)errorCode);
-
- CFRelease(cupsd_dict);
- }
-
- CFRelease(resourceData);
- }
-
- /*
- * Let the caller know we updated the file...
- */
-
- return (1);
- }
-
- return (0);
-}
#endif /* HAVE_LAUNCHD */
@@ -2155,5 +1778,5 @@ usage(int status) /* O - Exit status */
/*
- * End of "$Id: main.c 6365 2007-03-19 20:56:57Z mike $".
+ * End of "$Id: main.c 6493 2007-04-30 19:33:31Z mike $".
*/
diff --git a/scheduler/printers.c b/scheduler/printers.c
index 1934383ec..411efa495 100644
--- a/scheduler/printers.c
+++ b/scheduler/printers.c
@@ -1,5 +1,5 @@
/*
- * "$Id: printers.c 6436 2007-04-02 23:24:02Z mike $"
+ * "$Id: printers.c 6501 2007-04-30 21:53:15Z mike $"
*
* Printer routines for the Common UNIX Printing System (CUPS).
*
@@ -26,6 +26,7 @@
* cupsdAddPrinter() - Add a printer to the system.
* cupsdAddPrinterHistory() - Add the current printer state to the history.
* cupsdAddPrinterUser() - Add a user to the ACL.
+ * cupsdCreateCommonData() - Create the common printer data.
* cupsdDeleteAllPrinters() - Delete all printers from the system.
* cupsdDeletePrinter() - Delete a printer from the system.
* cupsdFindPrinter() - Find a printer in the list.
@@ -266,7 +267,7 @@ cupsdCreateCommonData(void)
*notifier; /* Current notifier */
static const int nups[] = /* number-up-supported values */
{ 1, 2, 4, 6, 9, 16 };
- static const ipp_orient_t orients[4] =/* orientation-requested-supported values */
+ static const int orients[4] =/* orientation-requested-supported values */
{
IPP_PORTRAIT,
IPP_LANDSCAPE,
@@ -289,7 +290,7 @@ cupsdCreateCommonData(void)
"1.0",
"1.1"
};
- static const ipp_op_t ops[] = /* operations-supported values */
+ static const int ops[] = /* operations-supported values */
{
IPP_PRINT_JOB,
IPP_VALIDATE_JOB,
@@ -413,6 +414,10 @@ cupsdCreateCommonData(void)
/* copies-supported */
ippAddRange(CommonData, IPP_TAG_PRINTER, "copies-supported", 1, MaxCopies);
+ /* cups-version */
+ ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_TEXT, "cups-version",
+ NULL, CUPS_SVERSION + 6);
+
/* generated-natural-language-supported */
ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
"generated-natural-language-supported", NULL, DefaultLanguage);
@@ -545,11 +550,11 @@ cupsdCreateCommonData(void)
/* operations-supported */
ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
"operations-supported",
- sizeof(ops) / sizeof(ops[0]) + JobFiles - 1, (int *)ops);
+ sizeof(ops) / sizeof(ops[0]) + JobFiles - 1, ops);
/* orientation-requested-supported */
ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
- "orientation-requested-supported", 4, (int *)orients);
+ "orientation-requested-supported", 4, orients);
/* page-ranges-supported */
ippAddBoolean(CommonData, IPP_TAG_PRINTER, "page-ranges-supported", 1);
@@ -1651,7 +1656,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
ipp_attribute_t *attr; /* Attribute data */
ipp_value_t *val; /* Attribute value */
int num_finishings; /* Number of finishings */
- ipp_finish_t finishings[5]; /* finishings-supported values */
+ int finishings[5]; /* finishings-supported values */
cups_option_t *option; /* Current printer option */
static const char * const sides[3] = /* sides-supported values */
{
@@ -2288,7 +2293,7 @@ cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
}
ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
- "finishings-supported", num_finishings, (int *)finishings);
+ "finishings-supported", num_finishings, finishings);
ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
"finishings-default", IPP_FINISHINGS_NONE);
}
@@ -3708,5 +3713,5 @@ write_irix_state(cupsd_printer_t *p) /* I - Printer to update */
/*
- * End of "$Id: printers.c 6436 2007-04-02 23:24:02Z mike $".
+ * End of "$Id: printers.c 6501 2007-04-30 21:53:15Z mike $".
*/