Should terminal applications guess what the user wants? - terminal

There was a small discussion about what git does and doesn't do by default for the user.
By default, colour is disabled (generally set up with git config), yet it sends its output to a pager application for certain commands (such as in git log).
One side to this would be that no flags should be enabled since it gives the user full control of the application. The contrary would state that when releasing a new application, one should try and win users over as quickly as possible with as many bells and whistles as possible.
This is probably a very subjective question, but in the year 2010 should terminal applications start making usability decisions by default or force its users to customize it.

$ rm file.txt </dev/null
Do you want to remove file.txt [y/n]
tty not connected, guessing "no"
So no; please avoid any assumptions because they can turn out to be the exact opposite of what is expected.
Color in git diff is disabled by default, because pagers may not support it — this is the case even for less, which needs to be explicitly invoked with the -R option to turn on escape sequence support.

if there are conditions when something acts differently like in the case of color when the output is a tty vs a pipe it should be clear what this condition is but git log doesn't check for this but some other programs do like ls in it's --color=auto mode
in the case of git log with --color it uses less with color escape code pass though on
if you want to override it give them a like a --color[=WHEH] option like ls has which can force color on regardless of the type of the output
--color[=WHEN] control whether color is used to distinguish file
types. WHEN may be `never', `always', or `auto'
the auto mode is what i describe in the first paragraph
the default should be the one useful to the users of the program, if there are cases where that default isn't what is wanted that's what options are for

The terminal applications are no exceptions. See oracle import (imp) it provides sensible defaults so even though it asks questions but a default selection is given a naive user would go for it unless he is really sure about that option. or even create database in oracle which has a smaller version which assumes all sensible defaults and an extended version.
One side to this would be that no
flags should be enabled since it gives
the user full control of the
application
User will learn to use full control if he actually starts using it. For instance I was evaluating workflow engines, open source ones, imagine for every workflow engine I needed to setup full infrastructure like database table structure before it even gets up and run. Instead one of the most sophisticated workflow engines gives nice HSQLDB implementation which works great for evaluation.
Once something starts working I can tweak it to suit me, rather than spending days on a software which seems quite dead in the beginning.

Related

Wayland detection from root user

I have a script that must be launched as root. I need to detect the graphics system and identify it (windows X system, Wayland).
I tried using some environment vars like ${XDG_SESSION_TYPE} or ${WAYLAND_DISPLAY} which are revealing if you are using x11 or wayland, or if you are in a headless system... but, the problem is that the vars are not working from root user. As you know, the graphics environment is usually launched by a normal user and as I said at the beginning of the question, for reasons that I'm not going to explain here, the script needs to be launched as root.
Next screenshot is showing only one common element between users, the XAUTHORITY var...
I could use that but I think that could be a very dirty way to do it. It must be a better way. Any suggestion? Thanks.
The only reliable method is for you to obtain the report, from the environment by a non-root user ID, of the XDG_SESSION_TYPE variable's value.
For X-Windows, XDG_SESSION_TYPE=x11
For Wayland, XDG_SESSION_TYPE=wayland
However, as datenwolf stated, since root is specifically hindered by hard-coded security precautions, even if you customized your root's .bashrc, you won't be able to get the GUI to respond reliably, if at all, depending on the tools and elements you use.
If, on the other hand, you are attempting to build a tool for specific use by high-level security specialists, then you will likely require a customized build of the OS (removing those hard-coded security blocks) to complement those tools. That ... is a huge task, which only those with deep pockets and unlimited resources ... can allow themselves to contemplate ... unless the developers were smart enough to anticipate such a need and have all those code segments "drop-out" during compilation with the appropriate compile-time flag turned on/off. :-)

X11 - How to get system colors?

I'm using X11 lib. Is it possible to get system colors? I mean from current user theme like face, highlight color etc. I can't use GTK and QT libs. Exists any way to get colors by some environment variable or freedesktop?
Regards
Prepare for some serious pain and confusion and anger. It could be all so simple, weren't both Qt and GTK+/GNOME serious cases of the NIH syndrome.
In X11 there is a system called X resources database which is effectively a key → value store where key and value are both strings and contained within a property of the root window. You can access it using the xrdb tool. Any well behaved X11 program uses this X resource database to adjust its appearance to that the user set.
The traditional X11 toolkits, Motif, Tk, Athena, Xaw3 and such conformed to this. And everything was well. And because there were set a simple, unambigous set of pattern matching rules nearly every aspect and every single widget could be themed this way.
When GTK+ and Qt were born they too adhered to the Xrdb. But soon the GTK+ and Qt developers said "this is not of our design, we do it our way", so GTK+ and Qt retrieve their settings from dotfiles in the user's homedirectory. And for compatiblity reasons also respect some, but not all, and with every version a different set of Xrdb keys.
Of course desktop libraries ought work together and so a lot of settings mangement systems were born: Elektra, gconf, dconf, uconf, and specifically for X11 Xsettings. gconf, dconf, uconf don't use the X11 protocol of course but propritary IPC or DBus. DBus in itself is rather flawed.
Xsettings however is a specification that's full of contradictions, doesn't work nearly as well as Xrdb does. The main "reason" for Xsettings to be there is, so that clients could be informed about changes, because instead of a property on the root window all the settings were managed by a Xsettings deamon, informing all clients on the screen of a change. And should the daemon die things would go back to default, because clients were supposed to register for the event emitted when the Xsettings daemon's InputOnly property holder window would go away. I have only one word for Xsetting wahrrrgarrrbl.
The Xsettings creators obviously never thought of that changing a window's properties creates a X event by itself, that allows clients to listen for settings changes. Also it makes no sense to get informed about settings changes only, because this requires all clients to keep track of their local settings state, even if some of their internal settings only indirectly depend on some settings. Parsing the whole Xrdb is easier, less error prone and the theoretical overhead savings of only processing a subset of changed settings is in stark contrast that settings don't change all the time.
It's on a long TODO list of mine, to strip Qt and GTK+ of the whole gconf, dconf, uconf, Xsettings and their propriatary config dotfile mess and make them use Xrdb and nothing else.

Supporting both This-User-Only and Local-Machine settings

I have an application that has to support modifying some registry data depending on the kind of 'installation' that is desired. At present, I have no problems hard-coding to either get elevation and do the changes to the entire local machine, but it is far from nice as ideally, I would also like to support per-user installations. I could hardcode that, but then I lose the local-machine stuff. To be precise, the changes in question involve file association changes, COM stuff etc.
How can I properly support both usage scenarios? Currently I use a set of ON/OFF checkboxes for the variety of associations.
Should I change this meaning on, for example, a MachineInstall file existing in my apps directory, and if not assume User install?
Is it an expected/valid/whatever usecase to say that someone might want to do some things for the entire machine, and some things only for the user? (E.g. mixing of the two.)
Or should I change the entire UI, move away from checkboxes and move to some sort of combobox going 'None/User/Local'? Then again, I think this might have some sort of breakage once you involve multiple users and combinations.
To give an indication, I personally expect the application in question to have its uses for everyone on a computer and as such lean towards the Local-Machine as a 'default', if that makes any sort of difference.
I am likely overthinking the matters quite a bit, so any and all input is very much appreciated. :)
P.S.
Now, someone is probably going to say 'do not do all that stuff from your app, do it from the installer instead'. And they probably have a point, but the point is to allow easy changing of these settings from within the application. To top it off, I am not using .MSI install packages because they make working with 32/64-bit specific executables a disaster requiring merge modules, spawning other MSI's depending on the situation, and so forth (I forgot the details last time I dug into it and forgot about the matter). I don't have that knowledge, nor the time to learn all the intricacies of MSI installations, so it is out for as far I am concerned. To boot, my application is perfectly capable of functioning without any of those registry entries being present, and that is by design. In a way, one might compare it to be like Process Explorer from Sysinternals, which does not require an installer, but can be unzipped and take over the task manager etc without a problem if a user wants, or simply run stand-alone.

Is a launchd daemon the best route to go for reading/writing to privileged files in Cocoa?

I have an application which needs to be able to write to Any User/Current host preference files (which requires admin privileges per Preferences Utilities Reference) and also to enable/disable a launchd agent via its plist (writable only by root).
I'm using SFAuthorizationView to require users to authenticate as an admin before altering these values.
I'm trying to decide on the best way to do the actual altering of these values.
The cheap hackish option seems to be to use AuthorizationExecuteWithPrivileges() and mv or defaults, either via BLAuthentication or creating something similar myself. The downside to this is not getting the return value of whatever command line app I'm executing, plus some odd esoteric bugs I've encountered (such as getting a -60008 error in certain situations). This is strongly recommended against by Apple, obviously, but people do seem to do it and have some success with it.
The second most hackish option would seem to be the whole create a helper app with the suid bit set and the --self-repair option as discussed in various places. This seems possible, but like it's probably not much less trouble than the third option.
The third option is to create a fully fledged launchd daemon which will run as root and communicate with my application via a socket. This seems like a bit of overkill to read and write some plist files, but it's also possible I may find other uses for it down the road, and it wont be the only daemon for my application, so it doesn't seem unreasonable to just add another.
I'm thinking about modifying this sample code for my purposes.
My two questions are:
Does the launchd daemon option seem like the best route to go for this, or is there a much easier route I'm missing?
Has anybody else successfully used that code as a basis for something similar, and does anybody see any glaring issues with it I'm missing? I've used it successfully in a test app, but I'd be curious to hear you guys' opinion on it.
launchd is definitely the best and safest way to go: you’ll need an installer package to get your helper into place. Do be sure that your helper does and can do absolutely nothing except edit the files you wish to target.
No experience w/the code, but it’s based off of BetterAuthorizationSample, so that’s a nice start.
There's also the openauth API, which allows you to open files that require root privileges.

How do you control printer tray selection for printer in Windows

We need to be able to change the default selected print tray of a given printer. Does anyone have VC++/win32 code for doing this?
In case it matters, I believe we have to change the default setting for the printer. Our print jobs are executed by an application other than ours, so we can't make these kinds of changes in the context of a print operation originating from inside our application. Unless there is some way to modify the default print settings in a different application, I think we are stuck changing the user's defaults for the printer, initiating our print job, then setting the defaults back to the original values.
We'd really prefer to have the defaults change for the current user only, and not require any special UAC elevation, etc...
I suspect that it will use something similar to what is shown in this MSDN article, and involve setting fields in the DEVMODE structure (either dmDefaultSource or dmFormName or both).
Any takers? Or does anyone have any gotchas they'd like to share?
EDIT: Here is a link for DEVMODE documentation DEVMODE documentation
EDIT: I should also point out that we are looking for a general solution - not something specific to a particular printer (we deploy in many, many environments)
FYI - the solution we wound up using was to capture the DEVMODE structure. We have a small win32 app that presents the printer settings dialog (via DocumentProperties with fMode set to DM_IN_PROMPT). The resultant DEVMODE is then saved to disk. When we do our printing, we capture the current DEVMODE, set the stored DEVMODE, initiate the print, then restore the original DEVMODE.
This actually works quite well. Occasionally, the print drivers will update and cause the stored DEVMODE to break, but that doesn't happen very often and it's easy enough for users to fix.
As an extra bonus, this approach allows us to capture ALL of the printer settings (not just the output tray) - so we were able to support advanced settings like stapling, collating, etc...
Tip: If you try this, be sure to write to disk as a binary output stream. In my initial evaluation of this approach, I accidentally set the output stream up as a text output stream. Things would work fine for many cases, then suddenly break for some printers (that used high order bytes in their DEVMODE private data). A dumb, but easy, mistake to make - and one that took a very nice solution off the table for awhile.
Setting features like this can be tricky, especially if the driver doesn't follow Microsoft's print guidelines. That being said, we've had some success with System.Drawing.Printing.PrinterSettings. You can set PaperSource but I'm not sure you can set the defaults.
If you haven't seen this example you may want to look further at it. It describes a method to store and reload printer settings. One of my guys pointed it to me:
PrinterSettings - Changing, Storing and Loading Printer Settings
Another method, that could work but might not work for you, is to determine your the handful of setups you need. Install a printer with each of these (ie: Tray 1, Tray 2) setups. Then simply switch the default printer on print. Not what you are looking for but it may help.
What we typically do in these situations is have the 3rd party app write the data to a folder that we are monitoring, we then pick up the file and parse the Postscript or PCL ourselves and change the paper tray and then send onto the destination device. A lot simpler then it may sound.
dmDefaultSource controls the tray. Unfortunately the values you'll want to set this to differs depending on your driver as this is a bin number and not necessarily the same number as the tray# printed on your printer.
The following link provides some VB6 code for gathering information about your printers tray/bin assignments. You can use that information to programatically assign dmDefaultSource to the appropriate bin # for a tray. You basically need to use DeviceCapabilities to return information about your printers and then search for a string (like "Tray 1") to get the associated bin number.
http://support.microsoft.com/kb/194789
I had to do something very similar recently on a specific printer driver and it required a vendor specific SDK. The tray doesn't seem to appear in DEVMODE or any of the other PRINTINFO_* structures so I guess I'd drop an email to the printer vendor.
As a last resort, I can think of two possible hacks. One is to automate the driver at GUI level using a scripted tool such as AutoIT. Second is to dump the registry to file, change the driver setting, dump the registry again, and compare the differences (may or may not work).
As far as I know, printers are controlled by the printer driver by sending them SNMP or PJL commands. But not all printers implement completely these sets of commands.
For HP printers I found at: http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?lang=en&cc=us&objectID=bpl07282&jumpid=reg_R1002_USEN some PJL commands (there are some related to the tray too).
I'm not sure this help, but take it as a hint for future searches...

Resources