blob: d691fbd1368c0b98b54505c12c2872bf944e303f [file] [log] [blame]
From c8797922c80ad9f8453915091164f898a03ff5e6 Mon Sep 17 00:00:00 2001
From: Brian Norris <briannorris@chromium.org>
Date: Mon, 25 Apr 2016 12:42:11 -0700
Subject: [PATCH] cupsd writes out its printer data to
$ServerRoot/{printers.conf,ppd/*.ppd}, alongside less volatile data, like
cupsd.conf and cups-files.conf. Some systems might like to keep the static
config files (i.e., ServerRoot) protected in a read-only partition, while
placing the volatile printer info in a writeable partition.
Support that with a new conf directive, PrinterRoot. If not supplied,
PrinterRoot defaults to ServerRoot.
Patch supplied upstream here:
https://www.cups.org/str.php?L4783
with additions for handling subscriptions, classes, and a few initial
oversights.
Signed-off-by: Brian Norris <briannorris@chromium.org>
Signed-off-by: Sean Kau <skau@chromium.org>
---
config.h.in | 1 +
cups-config.in | 5 +++++
cups/cups-private.h | 2 ++
cups/globals.c | 7 +++++++
cups/util.c | 2 +-
scheduler/classes.c | 4 ++--
scheduler/client.c | 6 +++---
scheduler/colorman.c | 4 ++--
scheduler/conf.c | 10 +++++++---
scheduler/conf.h | 2 ++
scheduler/cupsd.h | 2 ++
scheduler/ipp.c | 24 ++++++++----------------
scheduler/job.c | 2 +-
scheduler/main.c | 16 ++++++++++++++++
scheduler/printers.c | 10 +++++-----
scheduler/subscriptions.c | 4 ++--
systemv/lpstat.c | 4 ++--
17 files changed, 68 insertions(+), 37 deletions(-)
diff --git a/config.h.in b/config.h.in
index 15607eeca930..62dc085be5ce 100644
--- a/config.h.in
+++ b/config.h.in
@@ -128,6 +128,7 @@
#define CUPS_SBINDIR "/usr/sbin"
#define CUPS_SERVERBIN "/usr/lib/cups"
#define CUPS_SERVERROOT "/etc/cups"
+#define CUPS_PRINTERROOT CUPS_SERVERROOT
#define CUPS_STATEDIR "/var/run/cups"
diff --git a/cups-config.in b/cups-config.in
index 07726c5fabab..49b70f0581a5 100755
--- a/cups-config.in
+++ b/cups-config.in
@@ -30,6 +30,7 @@ sysconfdir=@sysconfdir@
cups_datadir=@CUPS_DATADIR@
cups_serverbin=@CUPS_SERVERBIN@
cups_serverroot=@CUPS_SERVERROOT@
+cups_printerroot=@CUPS_PRINTERROOT@
INSTALLSTATIC=@INSTALLSTATIC@
# flags for C++ compiler:
@@ -67,6 +68,7 @@ usage ()
echo " cups-config [--image] [--static] --libs"
echo " cups-config --serverbin"
echo " cups-config --serverroot"
+ echo " cups-config --printerroot"
echo " cups-config --version"
exit $1
@@ -117,6 +119,9 @@ while test $# -gt 0; do
fi
echo $libs
;;
+ --printerroot)
+ echo $cups_printerroot
+ ;;
--serverbin)
echo $cups_serverbin
;;
diff --git a/cups/cups-private.h b/cups/cups-private.h
index da8a3963bd05..f3e794faf9d0 100644
--- a/cups/cups-private.h
+++ b/cups/cups-private.h
@@ -66,6 +66,8 @@ typedef struct _cups_globals_s /**** CUPS global state data ****/
*cups_serverbin,/* CUPS_SERVERBIN environment var */
*cups_serverroot,
/* CUPS_SERVERROOT environment var */
+ *cups_printerroot,
+ /* CUPS_PRINTERROOT enviornment var */
*cups_statedir, /* CUPS_STATEDIR environment var */
*localedir; /* LOCALDIR environment var */
diff --git a/cups/globals.c b/cups/globals.c
index 4b041f47128b..7d0f93c83893 100644
--- a/cups/globals.c
+++ b/cups/globals.c
@@ -283,6 +283,9 @@ cups_globals_alloc(void)
if ((cg->cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL)
cg->cups_serverroot = confdir;
+ if ((cg->cups_printerroot = getenv("CUPS_PRINTERROOT")) == NULL)
+ cg->cups_printerroot = cg->cups_serverroot;
+
if ((cg->cups_statedir = getenv("CUPS_STATEDIR")) == NULL)
cg->cups_statedir = confdir;
@@ -304,6 +307,7 @@ cups_globals_alloc(void)
cg->cups_datadir = CUPS_DATADIR;
cg->cups_serverbin = CUPS_SERVERBIN;
cg->cups_serverroot = CUPS_SERVERROOT;
+ cg->cups_printerroot = CUPS_PRINTERROOT;
cg->cups_statedir = CUPS_STATEDIR;
cg->localedir = CUPS_LOCALEDIR;
}
@@ -322,6 +326,9 @@ cups_globals_alloc(void)
if ((cg->cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL)
cg->cups_serverroot = CUPS_SERVERROOT;
+ if ((cg->cups_printerroot = getenv("CUPS_PRINTERROOT")) == NULL)
+ cg->cups_printerroot = CUPS_PRINTERROOT;
+
if ((cg->cups_statedir = getenv("CUPS_STATEDIR")) == NULL)
cg->cups_statedir = CUPS_STATEDIR;
diff --git a/cups/util.c b/cups/util.c
index 2e9f688a7517..689f3cf2929f 100644
--- a/cups/util.c
+++ b/cups/util.c
@@ -844,7 +844,7 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAUL
struct stat ppdinfo; /* PPD file information */
- snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd", cg->cups_serverroot,
+ snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd", cg->cups_printerroot,
name);
if (!stat(ppdname, &ppdinfo) && !access(ppdname, R_OK))
{
diff --git a/scheduler/classes.c b/scheduler/classes.c
index 17add06ceacc..56be9055de5c 100644
--- a/scheduler/classes.c
+++ b/scheduler/classes.c
@@ -279,7 +279,7 @@ cupsdLoadAllClasses(void)
* Open the classes.conf file...
*/
- snprintf(line, sizeof(line), "%s/classes.conf", ServerRoot);
+ snprintf(line, sizeof(line), "%s/classes.conf", PrinterRoot);
if ((fp = cupsdOpenConfFile(line)) == NULL)
return;
@@ -671,7 +671,7 @@ cupsdSaveAllClasses(void)
* Create the classes.conf file...
*/
- snprintf(filename, sizeof(filename), "%s/classes.conf", ServerRoot);
+ snprintf(filename, sizeof(filename), "%s/classes.conf", PrinterRoot);
if ((fp = cupsdCreateConfFile(filename, ConfigFilePerm)) == NULL)
return;
diff --git a/scheduler/client.c b/scheduler/client.c
index 6a5e740b44e6..d438395cb14b 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -1069,7 +1069,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
char ppdname[1024];/* PPD filename */
snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd",
- ServerRoot, p->printers[i]->name);
+ PrinterRoot, p->printers[i]->name);
if (!access(ppdname, 0))
{
p = p->printers[i];
@@ -1129,7 +1129,7 @@ cupsdReadClient(cupsd_client_t *con) /* I - Client to read from */
char ppdname[1024];/* PPD filename */
snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd",
- ServerRoot, p->printers[i]->name);
+ PrinterRoot, p->printers[i]->name);
if (!access(ppdname, 0))
{
p = p->printers[i];
@@ -2948,7 +2948,7 @@ get_file(cupsd_client_t *con, /* I - Client connection */
return (NULL);
}
- snprintf(filename, len, "%s%s", ServerRoot, con->uri);
+ snprintf(filename, len, "%s%s", PrinterRoot, con->uri);
perm_check = 0;
}
diff --git a/scheduler/colorman.c b/scheduler/colorman.c
index 0d90dde54795..32221d937b8a 100644
--- a/scheduler/colorman.c
+++ b/scheduler/colorman.c
@@ -375,7 +375,7 @@ apple_register_profiles(
* Try opening the PPD file for this printer...
*/
- snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", ServerRoot, p->name);
+ snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", PrinterRoot, p->name);
if ((ppd = _ppdOpenFile(ppdfile, _PPD_LOCALIZATION_ICC_PROFILES)) == NULL)
return;
@@ -1393,7 +1393,7 @@ colord_register_printer(
* Try opening the PPD file for this printer...
*/
- snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", ServerRoot, p->name);
+ snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", PrinterRoot, p->name);
if ((ppd = _ppdOpenFile(ppdfile, _PPD_LOCALIZATION_ICC_PROFILES)) == NULL)
return;
diff --git a/scheduler/conf.c b/scheduler/conf.c
index f3e6514b28e1..3f4abee40e62 100644
--- a/scheduler/conf.c
+++ b/scheduler/conf.c
@@ -149,6 +149,7 @@ static const cupsd_var_t cupsfiles_vars[] =
{ "LPDConfigFile", &LPDConfigFile, CUPSD_VARTYPE_STRING },
{ "PageLog", &PageLog, CUPSD_VARTYPE_STRING },
{ "Printcap", &Printcap, CUPSD_VARTYPE_STRING },
+ { "PrinterRoot", &PrinterRoot, CUPSD_VARTYPE_STRING },
{ "RemoteRoot", &RemoteRoot, CUPSD_VARTYPE_STRING },
{ "RequestRoot", &RequestRoot, CUPSD_VARTYPE_STRING },
{ "ServerBin", &ServerBin, CUPSD_VARTYPE_PATHNAME },
@@ -879,6 +880,9 @@ cupsdReadConfiguration(void)
if (!ErrorLog)
cupsdSetString(&ErrorLog, CUPS_LOGDIR "/error_log");
+ if (!PrinterRoot)
+ cupsdSetString(&PrinterRoot, ServerRoot);
+
/*
* Read the cupsd.conf file...
*/
@@ -1205,7 +1209,7 @@ cupsdReadConfiguration(void)
SystemGroupIDs[0], 1, 1) < 0 ||
cupsdCheckPermissions(ServerRoot, NULL, 0755, RunUser,
Group, 1, 0) < 0 ||
- cupsdCheckPermissions(ServerRoot, "ppd", 0755, RunUser,
+ cupsdCheckPermissions(PrinterRoot, "ppd", 0755, RunUser,
Group, 1, 1) < 0 ||
cupsdCheckPermissions(ServerRoot, "ssl", 0700, RunUser,
Group, 1, 0) < 0 ||
@@ -1213,9 +1217,9 @@ cupsdReadConfiguration(void)
Group, 0, 0) < 0 ||
cupsdCheckPermissions(CupsFilesFile, NULL, ConfigFilePerm, RunUser,
Group, 0, 0) < 0 ||
- cupsdCheckPermissions(ServerRoot, "classes.conf", 0600, RunUser,
+ cupsdCheckPermissions(PrinterRoot, "classes.conf", 0600, RunUser,
Group, 0, 0) < 0 ||
- cupsdCheckPermissions(ServerRoot, "printers.conf", 0600, RunUser,
+ cupsdCheckPermissions(PrinterRoot, "printers.conf", 0600, RunUser,
Group, 0, 0) < 0 ||
cupsdCheckPermissions(ServerRoot, "passwd.md5", 0600, User,
Group, 0, 0) < 0) &&
diff --git a/scheduler/conf.h b/scheduler/conf.h
index 59cb15718e7c..e42c86e252c9 100644
--- a/scheduler/conf.h
+++ b/scheduler/conf.h
@@ -100,6 +100,8 @@ VAR char *ConfigurationFile VALUE(NULL),
/* cupsd.conf file to use */
*CupsFilesFile VALUE(NULL),
/* cups-files.conf file to use */
+ *PrinterRoot VALUE(NULL),
+ /* Root directory for printer configs */
*ServerName VALUE(NULL),
/* FQDN for server */
*ServerAdmin VALUE(NULL),
diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h
index f8b2c1195f45..9bfc0bc0de1e 100644
--- a/scheduler/cupsd.h
+++ b/scheduler/cupsd.h
@@ -199,6 +199,8 @@ extern void cupsdReleaseSignals(void);
extern void cupsdSetString(char **s, const char *v);
extern void cupsdSetStringf(char **s, const char *f, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
+extern void cupsdGetPPDPath(char *s, size_t s_size,
+ const cupsd_printer_t *p, int backup);
/* process.c */
extern void *cupsdCreateProfile(int job_id, int allow_networking);
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index b7c65fda3367..ac370d96e95f 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -2647,8 +2647,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
"Copied interface script successfully");
}
- snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
- printer->name);
+ cupsdGetPPDPath(dstfile, sizeof(dstfile), printer, 0);
if (!strncmp(line, "*PPD-Adobe", 10))
{
@@ -2695,8 +2694,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
printer->name);
unlink(dstfile);
- snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
- printer->name);
+ cupsdGetPPDPath(dstfile, sizeof(dstfile), printer, 0);
unlink(dstfile);
}
else
@@ -2709,8 +2707,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
printer->name);
unlink(dstfile);
- snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot,
- printer->name);
+ cupsdGetPPDPath(dstfile, sizeof(dstfile), printer, 0);
if (copy_model(con, attr->values[0].string.text, dstfile))
{
@@ -2760,8 +2757,7 @@ add_printer(cupsd_client_t *con, /* I - Client connection */
sizeof(scheme), username, sizeof(username), host,
sizeof(host), &port, resource, sizeof(resource));
- snprintf(srcfile, sizeof(srcfile), "%s/ppd/%s.ppd", ServerRoot,
- printer->name);
+ cupsdGetPPDPath(srcfile, sizeof(srcfile), printer, 0);
if ((ppd = _ppdOpenFile(srcfile, _PPD_LOCALIZATION_NONE)) != NULL)
{
for (ppdattr = ppdFindAttr(ppd, "cupsPortMonitor", NULL);
@@ -5712,11 +5708,9 @@ delete_printer(cupsd_client_t *con, /* I - Client connection */
printer->name);
unlink(filename);
- snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot,
- printer->name);
+ cupsdGetPPDPath(filename, sizeof(filename), printer, 0);
unlink(filename);
- snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd.O", ServerRoot,
- printer->name);
+ cupsdGetPPDPath(filename, sizeof(filename), printer, 1);
unlink(filename);
snprintf(filename, sizeof(filename), "%s/%s.png", CacheDir, printer->name);
@@ -6790,8 +6784,7 @@ get_ppd(cupsd_client_t *con, /* I - Client connection */
* See if we need the PPD for a class or remote printer...
*/
- snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot,
- dest->name);
+ cupsdGetPPDPath(filename, sizeof(filename), dest, 0);
if ((dtype & CUPS_PRINTER_REMOTE) && access(filename, 0))
{
@@ -6805,8 +6798,7 @@ get_ppd(cupsd_client_t *con, /* I - Client connection */
for (i = 0; i < dest->num_printers; i ++)
if (!(dest->printers[i]->type & CUPS_PRINTER_CLASS))
{
- snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot,
- dest->printers[i]->name);
+ cupsdGetPPDPath(filename, sizeof(filename), dest->printers[i], 0);
if (!access(filename, 0))
break;
diff --git a/scheduler/job.c b/scheduler/job.c
index 0fb0362a06e9..4ad199970488 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -965,7 +965,7 @@ cupsdContinueJob(cupsd_job_t *job) /* I - Job */
job->filetypes[job->current_file]->type);
snprintf(device_uri, sizeof(device_uri), "DEVICE_URI=%s",
job->printer->device_uri);
- snprintf(ppd, sizeof(ppd), "PPD=%s/ppd/%s.ppd", ServerRoot,
+ snprintf(ppd, sizeof(ppd), "PPD=%s/ppd/%s.ppd", PrinterRoot,
job->printer->name);
snprintf(printer_info, sizeof(printer_name), "PRINTER_INFO=%s",
job->printer->info ? job->printer->info : "");
diff --git a/scheduler/main.c b/scheduler/main.c
index 0656d68d8b9f..ed604a64c928 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -1278,6 +1278,22 @@ cupsdSetString(char **s, /* O - New string */
/*
+ * 'cupsdGetPPDPath()' - Get the path of the PPD for a particular printer.
+ */
+
+void
+cupsdGetPPDPath(char *s, /* O - Output string */
+ size_t s_size, /* I - Size of 's' */
+ const cupsd_printer_t *p, /* I - Printer */
+ int backup) /* I - Get the backup path (*.O)? */
+{
+ if (backup)
+ snprintf(s, s_size, "%s/ppd/%s.ppd.O", PrinterRoot, p->name);
+ else
+ snprintf(s, s_size, "%s/ppd/%s.ppd", PrinterRoot, p->name);
+}
+
+/*
* 'cupsdSetStringf()' - Set a formatted string value.
*/
diff --git a/scheduler/printers.c b/scheduler/printers.c
index 61956b74d1d8..db9cc19d56b4 100644
--- a/scheduler/printers.c
+++ b/scheduler/printers.c
@@ -855,7 +855,7 @@ cupsdLoadAllPrinters(void)
* Open the printers.conf file...
*/
- snprintf(line, sizeof(line), "%s/printers.conf", ServerRoot);
+ snprintf(line, sizeof(line), "%s/printers.conf", PrinterRoot);
if ((fp = cupsdOpenConfFile(line)) == NULL)
return;
@@ -1385,7 +1385,7 @@ cupsdSaveAllPrinters(void)
* Create the printers.conf file...
*/
- snprintf(filename, sizeof(filename), "%s/printers.conf", ServerRoot);
+ snprintf(filename, sizeof(filename), "%s/printers.conf", PrinterRoot);
if ((fp = cupsdCreateConfFile(filename, ConfigFilePerm & 0600)) == NULL)
return;
@@ -2790,8 +2790,8 @@ cupsdUpdatePrinterPPD(
* Get the old and new PPD filenames...
*/
- snprintf(srcfile, sizeof(srcfile), "%s/ppd/%s.ppd.O", ServerRoot, p->name);
- snprintf(dstfile, sizeof(srcfile), "%s/ppd/%s.ppd", ServerRoot, p->name);
+ cupsdGetPPDPath(srcfile, sizeof(srcfile), p, 1);
+ cupsdGetPPDPath(dstfile, sizeof(dstfile), p, 0);
/*
* Rename the old file and open the old and new...
@@ -3809,7 +3809,7 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */
if (stat(cache_name, &cache_info))
cache_info.st_mtime = 0;
- snprintf(ppd_name, sizeof(ppd_name), "%s/ppd/%s.ppd", ServerRoot, p->name);
+ cupsdGetPPDPath(ppd_name, sizeof(ppd_name), p, 0);
if (stat(ppd_name, &ppd_info))
ppd_info.st_mtime = 1;
diff --git a/scheduler/subscriptions.c b/scheduler/subscriptions.c
index cf8a90d6f884..127d19fefcf5 100644
--- a/scheduler/subscriptions.c
+++ b/scheduler/subscriptions.c
@@ -717,7 +717,7 @@ cupsdLoadAllSubscriptions(void)
* Open the subscriptions.conf file...
*/
- snprintf(line, sizeof(line), "%s/subscriptions.conf", ServerRoot);
+ snprintf(line, sizeof(line), "%s/subscriptions.conf", PrinterRoot);
if ((fp = cupsdOpenConfFile(line)) == NULL)
return;
@@ -1071,7 +1071,7 @@ cupsdSaveAllSubscriptions(void)
* Create the subscriptions.conf file...
*/
- snprintf(filename, sizeof(filename), "%s/subscriptions.conf", ServerRoot);
+ snprintf(filename, sizeof(filename), "%s/subscriptions.conf", PrinterRoot);
if ((fp = cupsdCreateConfFile(filename, ConfigFilePerm)) == NULL)
return;
diff --git a/systemv/lpstat.c b/systemv/lpstat.c
index 9c076cb255ca..5ba05ba46b34 100644
--- a/systemv/lpstat.c
+++ b/systemv/lpstat.c
@@ -1842,7 +1842,7 @@ show_printers(const char *printers, /* I - Destinations */
else if (make_model && !strstr(make_model, "Raw Printer"))
_cupsLangPrintf(stdout,
_("\tInterface: %s/ppd/%s.ppd"),
- cg->cups_serverroot, printer);
+ cg->cups_printerroot, printer);
}
_cupsLangPuts(stdout, _("\tOn fault: no alert"));
_cupsLangPuts(stdout, _("\tAfter fault: continue"));
@@ -1965,7 +1965,7 @@ show_printers(const char *printers, /* I - Destinations */
else if (make_model && !strstr(make_model, "Raw Printer"))
_cupsLangPrintf(stdout,
_("\tInterface: %s/ppd/%s.ppd"),
- cg->cups_serverroot, printer);
+ cg->cups_printerroot, printer);
}
_cupsLangPuts(stdout, _("\tOn fault: no alert"));
_cupsLangPuts(stdout, _("\tAfter fault: continue"));
--
2.8.0.rc3.226.g39d4020