After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 657706 - Incorrect parsing of lpoptions for default print options
Incorrect parsing of lpoptions for default print options
Status: RESOLVED OBSOLETE
Product: gtk+
Classification: Platform
Component: Printing
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2011-08-30 13:51 UTC by mskala
Modified: 2018-04-15 00:21 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description mskala 2011-08-30 13:51:40 UTC
Code in root/modules/printbackends/cups/gtkprintbackendcups.c that reads /etc/cups/lpoptions to determine the default settings currently ignores the "instance" field of the syntax completely, as well as ignoring the line that specifies which instance is default.  As a result, the default settings used are (for any given printer name) a combination of all the settings specified for all instances of that printer, with later-specified settings overriding earlier-specified settings.  This probably is not what the user wanted as default, and may not even be the same as any of the defined instances.

Steps to reproduce:  define an instance that specifies non-default settings, and define it last in /etc/cups/lpoptions, then try to print.

Actual results: printing dialogue will show settings from the last instance in the file, possibly combined with options from earlier instances if the last instance doesn't override them all.

Expected results: printing dialogue should show the default settings defined in the /etc/cups/lpoptions file according to its documented syntax.

Bug is present in current head revision, but has existed for years.

Some description of the bug is in this Web log posting: http://ansuz.sooke.bc.ca/entry/191

Some of the offending code is in http://git.gnome.org/browse/gtk+/tree/modules/printbackends/cups/gtkprintbackendcups.c around line 2536, where it strips off the instance name and just continues reading the file as if that were a reasonable thing to do.  I think this may have been introduced during the "fix" of bug number 469210.  Emmanuele Bassi's comment of 2007-8-31 notes that using fopen/fgets to parse the file is probably the wrong way to do it, but the bigger issue is that the syntax this code parses is just plain wrong - the file format doesn't work the way this code implies - never mind which library functions are being used to parse it.

I suspect that many other complaints about default printer settings (e.g. "it defaults to A4 when I wanted letter!" and vice versa) are actually consequences of this one.
Comment 1 André Klapper 2012-01-06 15:57:59 UTC
=> gtk+, as gnome-print is dead.
Comment 2 Matthijs Kooijman 2012-10-18 14:26:50 UTC
I ran into this bug as well using evince (but of course I couldn't find this bug report until I found the piece of code with the bug ;-p).

I intended to suggest to simply ignore all lines with a non-empty instance value, but I realized that the default destination can actually be set to a specific instance, which would again lead to unexpected results.

This would mean that:
 - If the (overall) default printer is set to an instance of a printer, the options associated with that instance should be used.
 - For all other printers, the options associated with the instance-less version should be used.

It seems the only way to really fix this is to use a two-pass system: First read all config files, to find out if the default printer is set to an instance of the printer we're interested in getting the options for and a second pass to actually parse the options (only using the lines for the instance we found in the first pass, or the empty instance if we found no instance in the first pass).

This two-pass thing would be a bit messy (though there are already two versions of the parsing in the code, for getting the default printer and getting the options, so extending cups_get_user_default_printer to also return the instance name should be fairly easy). Also, it's a bit weird that the global default printer will also select the "default instance" for the printer (in other words: Why is there no way to select the default instance for printers other than the default printer?).

The latter might suggest that picking a default instance based on the default printer might not make sense after all and instead the instance-less settings should be used for all printers instead. If this approach is taken, simply skipping any line with an instance defined should be enough after all.


A third option, which I think would be the most elegant way to fix this, is to show different instances as different printers in the dialog. This is the approach taken by openoffice.org/libreoffice as well (though it seems that they fail to actually parse the options and update the GUI based on the options, making it quite useless there. Given that the gtk code already succesfully handles this part, I think this would be a good option).
Comment 3 mskala 2012-10-19 15:21:28 UTC
"Instance" is not a configuration option applied to a printer.  It is part of the name of what CUPS calls a "destination."  Destinations, not printers, are the first-class entities of interest.  Two separate destinations may share a value for the "printer" field in their name, but they remain separate destinations.  GTK+ only knows about the connection between "zinc" and "zinc/plain" in detail at all because it insists on parsing CUPS's config files itself instead of using the API.

Since destinations (whose names include "printer" and "instance" fields) are the first-class entities that may be default or not, the idea of selecting a default instance for a non-default printer is nonsense.  That would be like saying "Our company is owned entirely by Joe Smith, but what is the first name of the owner who is not Mr. Smith?"  One destination is default.  Its name specifies both the printer and the instance.  The default printer and default instance have no meaning except together as the parts of the default destination.

Accordingly, your idea of showing the different instances as if they were different printers is the best way to handle this in the user interface, and as you mention, it's what other software does.  Destinations should be equivalent to what other backends call "printers" if (as I suspect) the issue is of wanting a GUI that will work with CUPS and also with other backends.

I don't think a two-pass parse is absolutely necessary, but it is necessary that the parser must remember all the options that could possibly apply to the selected destination until it knows which destination is selected.  Doing so necessitates either a two-pass parse (figure out the instance, then go back and look at the options for that instance) or a smarter data structure (load options for all instances and then look up the right ones).  It's an implementor's call which is the better approach.  The code is already doing an extra pass for much the same reason because of not knowing which "printer" will be default or user-selected; so if extra passes are a problem, the existing extra pass should be eliminated too.

Of course, using the CUPS API would eliminate the problem.

The current approach of mixing options between different instances is obviously wrong.  I don't like pretending the unnamed instance is always the default (by skipping lines that mention instances) either, because that specifically contradicts the definition of the file format.  It's a slap in the face to anyone who read the documentation and believed that GTK+ would work with CUPS or that the default configured in CUPS would really be the default in GTK+.  Why should "same printer as the default destination, but a hardcoded value for instance" be GTK+'s default?  It may have very little connection to the actual default.

I'd like to emphasize that this is not a small issue.  It's not just a question of "oh, the user has to make one more click to choose the settings they want."  One common consequence of disobeying the default destination setting is incorrect default paper size, which is a *dealbreaker*, possibly even for use of the entire operating system, in some educational computer labs because users can't be trusted (and in some cases are administratively forbidden) to change the options on every single job.  They inevitably print with the incorrect default and it causes the shared printers to stop and require professional operator intervention.  We have to get this right.
Comment 4 Matthias Clasen 2018-02-10 05:03:41 UTC
We're moving to gitlab! As part of this move, we are moving bugs to NEEDINFO if they haven't seen activity in more than a year. If this issue is still important to you and still relevant with GTK+ 3.22 or master, please reopen it and we will migrate it to gitlab.
Comment 5 Matthijs Kooijman 2018-02-10 09:19:58 UTC
I checked if this bug still exists, but I could not reproduce it in evince (it still does not show all instances as destinations, just the main printer names). However, it seems that Evince is no longer using the gtk lpoptions-parsing code, but instead gets its default options directly from cups (the default options I set in the cups webinterface were shown in evince, if I removed ~/.config/evince/print-settings, where it seems to remember the last used print settings).

Looking at the code, it seems that at least options of instances are no longer parsed, but it only parses the options for the instance-less entry in lpoptions. This at least prevents most of the confusion, but it still means that:
 - Instances are not shown as separate destinations
 - If an instance is selected as default in lpoptions, Cups uses the instance-less version of the same printer instead.

So I guess this particular bug is fixed, but it's not quite perfect yet. The fix is here, btw: https://gitlab.gnome.org/GNOME/gtk/commit/bf9c9f17627ebd049d8b2b5ccc6bab27ce37fcca

See also https://bugzilla.gnome.org/show_bug.cgi?id=753628 and https://bugzilla.gnome.org/show_bug.cgi?id=582747

Feel free to mark this bug as FIXED and perhaps as a duplicate of 753628?
Comment 6 mskala 2018-02-10 13:53:24 UTC
GTK 3.22.26 on my system doesn't seem to read lpoptions at all.  I don't know whether that's universal in this version, or whether it's just due to the peculiarities of my system.  If lpoptions is no longer where GTK gets its printer config, then bugs in parsing of lpoptions no longer matter.

However, if the code to read lpoptions is still part of the library, then that suggests it's likely to run at least occasionally on at least some systems.  And if it runs and it doesn't read and correctly apply the "Default" directive, then it is NOT correct and the bug is NOT fixed.  The default settings are the ones in the instance specified by the "Default" directive.  They are not necessarily the ones in the instance without a slash in its name.  Ignoring all configuration for instances with slashes in their names and always going to the instance with no slash, will make the configuration a little more understandable for users but no more correct.
Comment 7 Michael Weghorn 2018-03-15 11:27:27 UTC
(In reply to mskala from comment #6)
> GTK 3.22.26 on my system doesn't seem to read lpoptions at all. [...]

I'm not sure about version 3.22.26, but at least with version 3.22.28 in Debian testing, this does work.

For instances not being taken into account, there is also bug 148184. I have attached patches there a while ago and plan to add updated versions, but have no influence on whether anybody is going to have a look at them...
Comment 8 Matthias Clasen 2018-04-15 00:21:28 UTC
As announced a while ago, we are migrating to gitlab, and bugs that haven't seen activity in the last year or so will be not be migrated, but closed out in bugzilla.

If this bug is still relevant to you, you can open a new issue describing the symptoms and how to reproduce it with gtk 3.22.x or master in gitlab:

https://gitlab.gnome.org/GNOME/gtk/issues/new