/*
- * "$Id: dest.c 5138 2006-02-21 10:49:06Z mike $"
+ * "$Id: dest.c 6044 2006-10-17 20:32:59Z mike $"
*
* User-defined destination (and option) support for the Common UNIX
* Printing System (CUPS).
#include "globals.h"
#include <stdlib.h>
#include <ctype.h>
+#include <sys/stat.h>
#ifdef HAVE_NOTIFY_H
# include <notify.h>
/*
* 'cupsAddDest()' - Add a destination to the list of destinations.
*
- * Use the cupsSaveDests() function to save the updated list of destinations
- * to the user's lpoptions file.
+ * This function cannot be used to add a new class or printer queue,
+ * it only adds a new container of saved options for the named
+ * destination or instance.
+ *
+ * If the named destination already exists, the destination list is
+ * returned unchanged. Adding a new instance of a destination creates
+ * a copy of that destination's options.
+ *
+ * Use the cupsSaveDests() function to save the updated list of
+ * destinations to the user's lpoptions file.
*/
int /* O - New number of destinations */
-cupsAddDest(const char *name, /* I - Name of destination */
- const char *instance, /* I - Instance of destination or NULL for none/primary */
+cupsAddDest(const char *name, /* I - Destination name */
+ const char *instance, /* I - Instance name or NULL for none/primary */
int num_dests, /* I - Number of destinations */
cups_dest_t **dests) /* IO - Destinations */
{
int i; /* Looping var */
cups_dest_t *dest; /* Destination pointer */
+ cups_dest_t *parent; /* Parent destination */
+ cups_option_t *option; /* Current option */
- if (name == NULL || dests == NULL)
+ if (!name || !dests)
return (0);
if ((dest = cupsGetDest(name, instance, num_dests, *dests)) != NULL)
*dests = dest;
+ /*
+ * Find where to insert the destination...
+ */
+
for (i = num_dests; i > 0; i --, dest ++)
if (strcasecmp(name, dest->name) < 0)
break;
- else if (strcasecmp(name, dest->name) == 0 &&
- instance != NULL && dest->instance != NULL &&
+ else if (!instance && dest->instance)
+ break;
+ else if (!strcasecmp(name, dest->name) &&
+ instance && dest->instance &&
strcasecmp(instance, dest->instance) < 0)
break;
if (i > 0)
memmove(dest + 1, dest, i * sizeof(cups_dest_t));
+ /*
+ * Initialize the destination...
+ */
+
dest->name = strdup(name);
dest->is_default = 0;
dest->num_options = 0;
dest->options = (cups_option_t *)0;
- if (instance == NULL)
+ if (!instance)
dest->instance = NULL;
else
+ {
+ /*
+ * Copy options from the primary instance...
+ */
+
dest->instance = strdup(instance);
+ if ((parent = cupsGetDest(name, NULL, num_dests + 1, *dests)) != NULL)
+ {
+ for (i = parent->num_options, option = parent->options;
+ i > 0;
+ i --, option ++)
+ dest->num_options = cupsAddOption(option->name, option->value,
+ dest->num_options,
+ &(dest->options));
+ }
+ }
+
return (num_dests + 1);
}
*/
cups_dest_t * /* O - Destination pointer or NULL */
-cupsGetDest(const char *name, /* I - Name of destination */
- const char *instance, /* I - Instance of destination */
+cupsGetDest(const char *name, /* I - Destination name or NULL for the default destination */
+ const char *instance, /* I - Instance name or NULL */
int num_dests, /* I - Number of destinations */
cups_dest_t *dests) /* I - Destinations */
{
int comp; /* Result of comparison */
- if (num_dests == 0 || dests == NULL)
+ if (num_dests <= 0 || !dests)
return (NULL);
- if (name == NULL)
+ if (!name)
{
/*
* NULL name for default printer.
return (NULL);
else if (comp == 0)
{
- if ((instance == NULL && dests->instance == NULL) ||
+ if ((!instance && !dests->instance) ||
(instance != NULL && dests->instance != NULL &&
- strcasecmp(instance, dests->instance) == 0))
+ !strcasecmp(instance, dests->instance)))
return (dests);
}
* printer-info, printer-is-accepting-jobs, printer-is-shared,
* printer-make-and-model, printer-state, printer-state-change-time,
* printer-state-reasons, and printer-type attributes as options.
+ *
+ * Use the cupsFreeDests() function to free the destination list and
+ * the cupsGetDest() function to find a particular destination.
*/
int /* O - Number of destinations */
* printer-make-and-model, printer-state, printer-state-change-time,
* printer-state-reasons, and printer-type attributes as options.
*
+ * Use the cupsFreeDests() function to free the destination list and
+ * the cupsGetDest() function to find a particular destination.
+ *
* @since CUPS 1.1.21@
*/
int num_dests; /* Number of destinations */
cups_dest_t *dest; /* Destination pointer */
const char *home; /* HOME environment variable */
- char filename[1024]; /* Local ~/.lpoptions file */
+ char filename[1024]; /* Local ~/.cups/lpoptions file */
const char *defprinter; /* Default printer */
char name[1024], /* Copy of printer name */
*instance; /* Pointer to instance name */
}
/*
- * Load the /etc/cups/lpoptions and ~/.lpoptions files...
+ * Load the /etc/cups/lpoptions and ~/.cups/lpoptions files...
*/
snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot);
if ((home = getenv("HOME")) != NULL)
{
- snprintf(filename, sizeof(filename), "%s/.lpoptions", home);
+ snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home);
+ if (access(filename, 0))
+ snprintf(filename, sizeof(filename), "%s/.lpoptions", home);
+
num_dests = cups_get_dests(filename, num_dests, dests);
}
/*
* Validate the current default destination - this prevents old
- * Default lines in /etc/cups/lpoptions and ~/.lpoptions from
+ * Default lines in /etc/cups/lpoptions and ~/.cups/lpoptions from
* pointing to a non-existent printer or class...
*/
* 'cupsSetDests()' - Save the list of destinations for the default server.
*
* This function saves the destinations to /etc/cups/lpoptions when run
- * as root and ~/.lpoptions when run as a normal user.
+ * as root and ~/.cups/lpoptions when run as a normal user.
*/
void
* 'cupsSetDests2()' - Save the list of destinations for the specified server.
*
* This function saves the destinations to /etc/cups/lpoptions when run
- * as root and ~/.lpoptions when run as a normal user.
+ * as root and ~/.cups/lpoptions when run as a normal user.
*
* @since CUPS 1.1.21@
*/
int wrote; /* Wrote definition? */
cups_dest_t *dest; /* Current destination */
cups_option_t *option; /* Current option */
+ _ipp_option_t *match; /* Matching attribute for option */
FILE *fp; /* File pointer */
const char *home; /* HOME environment variable */
char filename[1024]; /* lpoptions file */
*/
if ((home = getenv("HOME")) != NULL)
+ {
+ /*
+ * Remove the old ~/.lpoptions file...
+ */
+
snprintf(filename, sizeof(filename), "%s/.lpoptions", home);
+ unlink(filename);
+
+ /*
+ * Create ~/.cups subdirectory...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/.cups", home);
+ if (access(filename, 0))
+ mkdir(filename, 0700);
+
+ snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home);
+ }
}
#endif /* !WIN32 */
return (-1);
}
+#ifndef WIN32
+ /*
+ * Set the permissions to 0644 when saving to the /etc/cups/lpoptions
+ * file...
+ */
+
+ if (!getuid())
+ fchmod(fileno(fp), 0644);
+#endif /* !WIN32 */
+
/*
* Write each printer; each line looks like:
*
for (j = dest->num_options, option = dest->options; j > 0; j --, option ++)
{
+ /*
+ * See if this option is a printer attribute; if so, skip it...
+ */
+
+ if ((match = _ippFindOption(option->name)) != NULL &&
+ match->group_tag == IPP_TAG_PRINTER)
+ continue;
+
/*
* See if the server/global options match these; if so, don't
* write 'em.
*/
- if (temp && (val = cupsGetOption(option->name, temp->num_options,
- temp->options)) != NULL)
- {
- if (strcasecmp(val, option->value) == 0)
- continue;
- }
+ if (temp &&
+ (val = cupsGetOption(option->name, temp->num_options,
+ temp->options)) != NULL &&
+ !strcasecmp(val, option->value))
+ continue;
/*
* Options don't match, write to the file...
if (option->value[0])
{
- if (strchr(option->value, ' ') != NULL)
- fprintf(fp, " %s=\"%s\"", option->name, option->value);
- else
+ if (strchr(option->value, ' ') ||
+ strchr(option->value, '\\') ||
+ strchr(option->value, '\"') ||
+ strchr(option->value, '\''))
+ {
+ /*
+ * Quote the value...
+ */
+
+ fprintf(fp, " %s=\"", option->name);
+
+ for (val = option->value; *val; val ++)
+ {
+ if (strchr("\"\'\\", *val))
+ putc('\\', fp);
+
+ putc(*val, fp);
+ }
+
+ putc('\"', fp);
+ }
+ else
+ {
+ /*
+ * Store the literal value...
+ */
+
fprintf(fp, " %s=%s", option->name, option->value);
+ }
}
else
fprintf(fp, " %s", option->name);
/*
- * End of "$Id: dest.c 5138 2006-02-21 10:49:06Z mike $".
+ * End of "$Id: dest.c 6044 2006-10-17 20:32:59Z mike $".
*/