kov changed libgksu/tags/2.0.9/, libgksu/tags/2.0.9/ChangeLog, libgksu/tags/2.0.9/ChangeLog, libgksu/tags/2.0.9/libgksu/gksu-run-helper.c, libgksu/tags/2.0.9/libgksu/gksu-run-helper.c, libgksu/tags/2.0.9/libgksu/libgksu.c, libgksu/tags/2.0.9/libgksu/libgksu.c

Gustavo Noronha kov at alioth.debian.org
Wed Mar 4 18:55:14 UTC 2009


Mensagem de log: 
tagging 2.0.9

-----


Copied: libgksu/tags/2.0.9 (from rev 840, libgksu/trunk)

Deleted: libgksu/tags/2.0.9/ChangeLog
===================================================================
--- libgksu/trunk/ChangeLog	2009-02-23 02:20:27 UTC (rev 840)
+++ libgksu/tags/2.0.9/ChangeLog	2009-03-04 18:55:14 UTC (rev 848)
@@ -1,1528 +0,0 @@
-2009-02-22  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c: - added threads protection for the gdk
-	fadeout/fadein animation, so that callers will not have X errors
-	when trying to use gdk functions in parallel with us
-	See http://bugzilla.gnome.org/show_bug.cgi?id=549760.
-
-2009-02-22  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac, libgksu/libgksu.{c,h}, libgksu/gksu-run-helper.c:
-	- accepted patch by Joshua Kwan <jkwan at vmware.com> to
-	  return the same status code as the child
-
-2009-02-03  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added th to ALL_LINGUAS
-
-2008-08-29  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c: patch by Daniel Richard G. <skunk at iSKUNK.ORG>
-	to allow changing the location of the lockfile, so that libgksu
-	will work on AFS/NFS mounted home directories
-
-2008-06-20  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-run-helper.c: accepted patch by Michael Vogt, from
-	Ubuntu, to fix very long commands not fitting in the helper's
-	statically-sized buffer (Debian bug #486087, launchpad #173757)
-
-	* libgksu/libgksu.c (sudo_full): accepted patch by Michael Vogt,
-	from Ubuntu, to fix sudo having problems resolving network
-	addresses breaking gksu (Debian bug #486083, launchpad #237325)
-
-2008-05-27  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 2.0.7
-
-	* libgksu/libgksu.c (gksu_sudo_full): accepted patch by Ben
-	Hutchings <ben at decadent.org.uk> to also disable nonblocking I/O
-	when no password is asked (Debian bug #463709)
-
-	* configure.ac: - remove \n from the test code used to test for
-	the presence of the -version-script linker option; that was
-	causing the test to fail
-
-2008-05-16  Gustavo Noronha Silva  <Gustavo Noronha Silva <kov at alfaiati.net>>
-
-	* Release 2.0.6
-
-2008-01-02  Guilherme de S. Pastore  <gpastore at debian.org>
-
-	* libgksu/libgksu.c (gksu_sudo_full): fix typo introduced with the latest
-	  changes ("aways").
-
-2007-12-31  Gustavo Noronha Silva  <kov at cenoura>
-
-	* libgksu/libgksu.c:
-	- format parameters were wrong for the case in which you
-	  ask gksu to run a given command as a given user (other than
-	  root); thanks to Uwe Kleine-König <ukleinek at informatik.uni-freiburg.de>
-	  for pointing out; Debian bug #449180
-
-	* libgksu/libgksu.c:
-	- accepted patch from Ubuntu by Michael Vogt to add a new
-	  property for GksuContext: always_ask_password; the patch
-	  suffered minor aditions by me to also implement the functionality
-	  to the su backend and document the limitations (Debian bug #453423)
-
-	* libgksuui/gksuui-dialog.c:
-	- accepted patch from Ubuntu by Michael Vogt that fixes
-	  the capslock notification so that it doesn't change the
-	  size of the window (Debian bug #453426)
-
-2007-06-22  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- accepted patch from Ubuntu, by Michael Vogt, that
-	  fixes the way gksu waits for the child process to
-	  finish; see:
-	https://bugs.launchpad.net/ubuntu/+source/libgksu/+bug/121581
-
-2007-06-10  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 2.0.5
-
-	* libgksu/libgksu.c:
-	- also complete launch notification when cancel is
-	  pressed in the dialog; (Addressing Debian Bug #426495)
-
-2007-06-09  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- reworked the way gksu_su{,do}_full relays the child's
-	  output, making it sleep rather than wakeup every
-	  few microseconds (Addressing Debian Bug #425679)
-
-2007-05-11  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added sv and zh_CN.po to ALL_LINGUAS
-
-2007-03-28  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added ko to ALL_LINGUAS
-
-2007-03-06  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- always try to create the keyring when setting the password;
-	  if the keyring exists this is a no-op, so no problems
-	  (Addressing Debian Bug #412681)
-
-	* libgksu/libgksu.c:
-	- improved debugging for getting the password from the
-	  GNOME Keyring; and do not show the password anymore when
-	  debugging
-
-2007-03-04  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- accepted patch by Michael Vogt to handle the
-	  better quoted strings given by gksu
-
-2007-02-04  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 2.0.4
-
-2007-01-22  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.[ch]:
-	- accepted patch by "Gian Mario Tagliaretti"
-	  <g.tagliaretti at gmail.com> to turn GksuContext into
-	  a boxed type, so that it can be used in a saner way
-	  in bindings
-
-2007-01-05  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- accepted patch by Виталий Ищенко <betalb at gmail.com>
-	  which makes libgksu only replace the 'password typing' character
-	  when '*' is the default one
-
-2006-12-07  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- make sure DESKTOP_STARTUP_ID is set in the environment correctly
-
-2006-10-31  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- remove a trailing \n if it exists in the password we get from
-	  the GNOME Keyring (Addresses Debian Bug #395462)
-
-2006-10-23  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 2.0.3
-
-	* libgksu/libgksu.c:
-	- make sure the dialog is _destroyed_ instead of just being
-	  hidden, after some action has been taken in the dialog that
-	  asks for the password
-	- returns WRONGAUTOPASS instead of WRONGPASS when wrong password
-	  is the one we got from the gnome keyring
-	- store the password in the GNOME Keyring without the \n
-	  (Addresses Debian Bug #394895)
-
-2006-10-22  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 2.0.2
-
-	* libgksu/libgksu.c:
-	- make sure we notice ECHO disabled, and remove some uneeded waits
-	  which will probably speedup using su with password, but probably
-	  slow down su without password; this should avoid deadlocks when
-	  su delays setting ECHO off.
-
-2006-10-15  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksuui/gksuui-dialog.c:
-	- try to always have focus, by traping the focus-out-event;
-	  should address Debian bug #391804
-
-2006-10-08  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 2.0.1
-
-	* libgksu/libgksu.c:
-	- use some brute force reading when using sudo, to be able
-	  to handle stuff like the sudo lecture and pam modules debugging
-
-2006-10-01  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- if xauth is an empty string when using the su backend,
-	  then try to get it again by striping the hostname part
-	  of the display string; this is needed for ssh X forwarding
-
-2006-09-23  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- version set to 2.0.0; releasing libgksu 2, at last!
-
-2006-09-07  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- have gksu ignore lines coming from the process 'till it is able
-	  to find the gksu: waiting line; this is done observing some
-	  time and size constraints, though, so we won't end up in an infinite
-	  loop; this addresses #17139; libpam-mount should now work happily with
-	  debug on
-	- also make su's child session leader, like sudo's, so that when the
-	  program you ran launches another, closing the first will not destroy
-	  the second
-
-2006-09-02  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added it to ALL_LINGUAS
-
-2006-08-19  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added lt to ALL_LINGUAS
-
-	* libgksu/libgksu.c:
-	- add gettext call in the prompt in su_ask_password, so that
-	  the prompt is translated
-
-2006-08-15  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- accepted patch by Michael Vogt to fix the detection of
-	  sudo password failure by making the fd block while expecting
-	  the line right after the password is sent to sudo
-
-2006-08-06  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.9.8
-
-	* libgksu/libgksu.c:
-	- bring the rest of the startup notification code from the
-	  application
-
-2006-07-19  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.9.7
-
-	* libgksuui/gksuui-dialog.{c,h}:
-	- gksuui_dialog_init is not called after the properties
-	  are set, so post-pone creating the gnome-keyring UI
-	  when they are; also fixes a logic error
-
-2006-07-16  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.9.6
-
-	* libgksuui/gksuui-dialog.c, libgksu/libgksu.c:
-	- add a new object property to GksuuiDialog, and pass
-	  the sudo_mode boolean to it on object instanciation,
-	  so that the sudo window will not have the gnome_keyring
-	  stuff, again
-
-	* libgksu/libgksu.c[gksu_sudo_full]:
-	- use select in the read side of the parent_pipe, so that
-	  the sudo prompt will not show up after the non-blocking
-	  read is done (addresses Debian bug #377746)
-	- do not remove the hostname/socket part of the DISPLAY
-	  (addresses Debian bug #349652)
-
-2006-07-12  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.9.5
-
-	* libgksu/libgksu.{c,h}:
-	- add accessor methods for the startup notification launcher
-	  context
-
-2006-07-10  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- increment version to 1.9.5
-
-	* libgksu/libgksu.{c,h}, libgksuui/gksu-dialog.{c,h}:
-	- implement a new 'alert' label, to allow applications showing
-	  messages like 'wrong password, try again'
-
-2006-07-05  Gustavo Noronha Silva  <kov at debian.org>
-
-	* gksu.png, gksu-properties/{Makefile.am,gksu-properties.desktop.in,
-	  gksu-properties.c}:
-	- added an icon, and a desktop file so that the capplet will show in
-	  the preferences menu for the desktop
-
-2006-07-03  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- remove \n from the check of the command name, since gtop
-	  does not give a \n-terminated string; thanks to
-	  Benoît Dejean <benoit at placenet.org> for pointing this out
-
-2006-06-29  Gustavo Noronha Silva  <kov at debian.org>
-
-	* gksu-properties/*:
-	- start a simple capplet to configure the gksu gconf
-	  preferences
-
-	* libgksu/defines.h:
-	- small adaption so it can better be used by gksu-properties
-
-2006-06-26  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.9.4
-
-	* libgksu/libgksu.c:
-	- correctly derreference the error pointer when checking
-	  if something was returned by ask_pass
-
-2006-06-25  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.9.3
-
-	* libgksu/libgksu.c:
-	- use TRUE for success and FALSE for failure, to match glib's
-	  spawn API - well, it's a development release =D
-
-	* libgksu/libgksu.c:
-	- handle canceling the dialog correctly; added a new
-	  error to the enum
-
-	* configure.ac, libgksu/libgksu.c:
-	- accepted patch by Benoît Dejean <benoit at placenet.org>
-	  to get the process name in a platform independent way
-
-2006-05-01  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added fr to ALL_LINGUAS
-
-	* configure.ac, libgksu/Makefile.am:
-	- only use the version script if the system we're
-	  building on supports it; thanks to Daniel Macks
-	  for the patch
-
-	* libgksu/libgksu.c:
-	- check fread's return value before using strlen
-	  and setting a \0 in the xauth string, to prevent
-	  problems when xauth returns nothing (#7698)
-	- handle locales which mess with the 'su:' layout
-
-	* Release 1.9.2
-
-	* configure.ac:
-	- fixed gettext domain define
-
-2006-04-30  Gustavo Noronha Silva  <kov at debian.org>
-
-	* docs/*:
-	- updated documentation
-
-	* libgksu/Makefile.am:
-	- increased minor version of the library, since some
-	  symbols were added
-
-	* libgksuui/Makefile.am:
-	- do not build a static version of the lib only;
-	  I need a shared version with PIC symbols built so
-	  that libgksu will be able to be fully PIC
-
-	* libgksu/libgksu.c:
-	- provide an API for simply getting the password
-	- standardize the get methods that return string to
-	  return NULL if they were not set, and updated
-	  "docstrings" to fit;
-	- removed translatable marks for strings that are
-	  errors printed to stderr
-	- made some strings look better or more HIG compliant
-
-	* libgksuui/libgksu.{c,h}, libgksuui/gksuui-dialog.c:
-	- accepted changes from the Ubuntu people to make the dialog
-	  and messages be more beatiful; also provide an API that
-	  enables specifying a descriptional name for the command, that
-	  is used automatically in the message
-
-	* libgksuui/gksuui-dialog.c:
-	- do not center the label that is used to display
-	  the message
-
-2006-04-24  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- use the internal context->sudo_mode to tell the
-	  ask_pass function if we're on su or sudo mode
-
-	* libgksu/libgksu.{c.h}:
-	- implemented the message setting and getting
-	  functions, and use the message that is given
-	  when creating the dialog
-
-	* Release 1.9.1
-
-2006-04-23  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu2.pc.in:
-	- add gnome-keyring-1 and gconf-2.0 as dependencies
-
-	* Release 1.9.0
-
-	* libgksu/test-gksu.c:
-	- display message before testing gksu_sudo_full, so we
-	  get a better picture of where stuff is happening
-	- add a test to the new gksu_run{,_full} API
-
-	* libgksu.c:
-	- use non-blocking read when looking for the sudo prompt,
-	  so that we won't get blocked if there is none; also,
-	  make sure the window is displayed
-	- (su) track that gnome keyring was used to enhance the pass_not_needed
-	  display logic; display it parallel to running the command, to match
-	  gksu_sudo_full behavior
-	- only print the password when on debug mode
-	- init sn_context with NULL, so non-SN-supporting users will
-	  not segfault when we check for the value
-
-	* libgksu/libgksu.{c,h}:
-	- new API gksu_run{,_full}, that is a generic way of using
-	  gksu functionality, leaving the choice of su or sudo backend
-	  to the gconf setting
-
-2006-04-16  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- used suggestion by Benoît Dejean <benoit at placenet.org>
-	  to avoid buffer overflows on the debug code
-
-	* libgksu/libgksu.c:
-	- patch from Michael Vogt to fix corner condition which
-	  happens when fgets returns badly with a specific app
-
-2006-04-15  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c, libgksu/gksu-run-helper.c:
-	- check for xauth at /usr/bin (Xorg 7.0) and /usr/X11R6/bin
-	  (Xorg 6.9 and XFree86) [merged from trunk]
-
-2006-03-12  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksuui/gksuui-dialog.c:
-	- added UI for the gnome-keyring support in the main widget
-
-	* libgksu/libgksu.c:
-	- Preliminary support for gnome-keyring imported from the
-	  gksu app code; it now removes the password from the
-	  keyring in case it tries with it and fails
-
-2006-03-02  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added dependency on libstartup-notification-1.0 to
-	  PKG_CHECK_MODULES; startup notification support has
-	  been added!
-
-	* libgksu/test-gksu.c:
-	- use the new location for xterm (FHS-compliant)
-
-	* libgksu/libgksu.c:
-	- integrated patch by Michael Vogt to support startup notfication
-	- added accessor methods for the GksuContext structure, I want it
-	  to be opaque
-
-	* libgksu/Makefile.am, libgksu/libgksu2.pc.in:
-	- misc fixes to build system
-
-2006-01-24  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksuui/gksuui-dialog.{c,h}:
-	- applied patch by Michael Vogt to report that capslock is enabled
-	  with small modifications
-
-2006-01-07  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c, docs/*:
-	- revamp documentation; gtk-doc-style comments added to
-	  functions and some fixes to return values were made to
-	  match the docs
-
-	* configure.ac, Makefile.am, others:
-	- revamping the i18n infra-structure; mainly removing
-	  local intl/ copy and updating files
-	- do not use local copies of m4 files in a m4/ directory
-
-	* configure.ac:
-	- do not create pkg-config files for libgksuui; it won't
-	  be installed anymore
-
-	* Make libgksuui a sub, static library for libgksu only.
-	- removed gksu-convenience stuff, that is not going to
-	  be used anymore
-
-2005-12-11  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Major design overhaul
-	- incorporating libgksuui
-	- no longer try to be UI independent; use GTK+ mercylessly
-	- incorporating gconf schema and settings handling
-	- massive API review, removal of most public functions;
-	  GksuContext is no longer a GObject-based object, no longer
-	  has many accessor functions for its data fields and is
-	  needed for the _full versions of the main API functions
-	  right now; this allows saner handling of password prompting
-	  and housekeeping
-
-	* gksu.schemas.in:
-	- remove always-ask-password for now, it will probably be
-	  replaced by something else when gnome-keyring is integrated
-
-	* intltoolized, modified some stuff for the package
-	  renaming to work
-
-	* libgksu/libgksu.c:
-	- integrated 'prompt before grab' support; also make the
-	  foce-grab configuration effective
-
-	* renaming files:
-	- libgksu/gksu-context.{c,h} -> libgksu/libgksu.{c,h}
-
-2005-11-23  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.3.7
-
-2005-11-17  Gustavo Noronha Silva  <kov at debian.org>
-
-        Following 4 fixes were done with information and help
-	provided by Benoît Dejean <benoit at placenet.org>; thanks!
-
-	* libgksu/gksu-context.c:
-	- change debug message for the case in which we can't find
-	  a password prompt
-
-	* libgksu/gksu-context.c:
-	- do not free the user component of the context struct
-	  twice
-
-	* libgksu/gksu-context.c:
-	- init buffer with {0} so that debuging information will
-	  not show crappy stuff for it
-
-	* libgksu/gksu-context.c:
-	- check if pass_not_needed is there before calling
-	  it on gksu_context_sudo_run_full
-
-2005-10-25  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.3.6
-
-2005-10-02  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.c:
-	- fix logic problem when checking if what was read does not
-	  start with "gksu" or "su" - thanks to Guilherme de S. Pastore
-          for spotting the problematic range of code (Debian bug #331124)
-
-2005-09-29  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.3.5
-
-	* libgksu/gksu-context.c:
-	- fixed some memory leaks which were added by lack of
-	  caution on my part =/
-
-2005-09-28  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.3.4
-
-	* relibtoolized with libtool --automake -c -f
-	  (Debian's libtool 1.5.20-1)
-
-	* configure.ac: bump version to 1.3.4
-
-	* libgksu/gksu-context.c:
-	- apply the same solution to handling error return
-	  checking to the su backend
-
-2005-09-21  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.c:
-	- handle 'not in sudoers' message (Ubuntu's #14922)
-
-2005-09-18  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.c:
-	- applied a patch to use /proc information to find out the
-	  name of the current child process to check if it was sudo
-	  who returned a failure code or the app we called on Linux
-	  systems; patch and modifications done to it were made by
-	  Michael Vogt and his advice, respectively (Ubuntu's #7517)
-
-2005-09-12  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.c:
-	- treat the command line to remove the quotes that may have
-	  been added by gksu's multi-argument processing code
-
-2005-08-20  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.{c,h}:
-	- improve error reporting for sudo; tries to detect if sudo
-	  reported that the user cannot run the command for that user
-
-2005-08-02  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.3.3
-
-	* libgksu/Makefile.am:
-	- undo soname change because I stepped back from breaking the ABI
-
-	* libgksu/gksu-context.{c,h}:
-	- leave ask_and_run as deprecated functions to let software which
-	  used it at some point in development keep building and running
-
-	* libgksu/gksu-context.{c,h}:
-	- replaced ask_and_run with run_full for both su and sudo; the
-	  new API function which accepts another callback function that
-	  allows the user application to do something if a password was
-	  not needed like, for example, warning the user
-
-2005-08-01  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.c, libgksu/Makefile.am, configure.ac:
-	- revert inclusion of gnome-keyring support, which should
-	  actually go into the app, not the lib
-
-2005-07-21  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/Makefile.am:
-	- increased minor version number because of the adition
-	  to the API
-
-	* libgksu/gksu-context.{c,h}, libgksu/test-gksu.c:
-	- implemented the gksu_context_ask_and_run counterpart
-	  for sudo
-
-2005-07-14  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.3.2 - The "Helsinki" Release!
-
-	* libgksu/Makefile.am:
-	- increase library minor version because API was added without
-	  breaking ABI (yet! =D)
-
-	* libgksu/gksu-context.c:
-	- wrap the keyring callback in the ENABLE_GNOME_KEYRING
-	  ifdef
-
-	* libgksu/gksu-context.c, docs/libgksu1.2-sections.txt:
-	- make sure every public API function is documented
-
-	* libgksu/gksu-context.c:
-	- small fixes and improvements to some info and error messages
-
-	* libgksu/gksu-context.c:
-	- handle the droping of the \n echoed after password was given
-	  if a password needed to be given, so we have wheel trust and
-	  other situations in which you don't need a password handled
-	  correctly
-
-2005-07-13  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.c:
-	- kill su in try_su_run instead of simply sending a "\n" if it
-	  asks for password, so we improve speed and avoid dead locks
-
-	* libgksu/gksu-context.c:
-	- after-password conversation with helper improved quite a bit
-	  and made simpler; should fix some problems with gksu-run:
-	  strings coming out eventually and prevent some cases of dead
-	  locks
-
-	* libgksu/gksu-context.c:
-	- accepted patch by Aurelien Jacobs <aurel at gnuage.org> that
-	  moves the keyring_create_item_cb outside of the function
-	  which calls it, so gksu will not segfault on AMD64, which
-	  does not permit execution of the stack; this addresses
-	  Debian bugs #318031, #307975 and #314369.
-
-2005-07-12  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.c:
-	- also use the ECHO trick for try_su_run
-
-	* libgksu/gksu-context.c:
-	- OK, so the call to usleep must be inside the while loop so
-	  gksu won't be eating CPU time
-
-2005-07-11  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/test-gksu.c:
-	- fixed su_ask_pass declaration to include the GError** argument
-
-	* libgksu/gksu-context.c:
-	- init buf on gksu_context_ask_and_run with \0's so we don't get 
-	  random weird stuff at the first time we read something to it
-
-	* libgksu/gksu-context.c:
-	- better checking of whether a prompt is waiting for a password
-	  or not to figure out if a password is needed or not; this enhances
-	  the 'only ask for password if really needed' approach and is one 
-	  more step on addressing Debian's #246652; this required some 
-	  tweaking to the logic used in conversation with gksu-run-helper.
-
-	* libgksu/gksu-context.c:
-	- Fixed wording on xauth warning message so it will not use first
-	  person; this addresses Debian bug #309563.
-
-2005-07-09  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.c:
-	- kill sudo when trying validation and wait a bit before
-	  wait()'ing, so gksu gets blocked for less time
-
-2005-06-29  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.{c,h}:
-	- modified the password-asking function to receive a GError**
-	  so we have the possibility of creating a 'problem reporting'
-	  interface for it
-	- also, check the return value of the function and bail out
-	  if it is FALSE
-
-2005-06-28  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.c:
-	- make a gksu_context_ask_and_run that receives a function
-	  pointer to request password if needed (so you don't have
-	  to fill context->password beforehand)
-	* libgksu/test-gksu.c:
-	- also test the new API function
-
-2005-06-18  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.3.1
-
-	* libgksu/test-gksu.c:
-	- s/strings.h/string.h/
-
-	* libgksu/gksu-context.c:
-	- call try_su_run before the gnome-keyring test; this solves
-	  lots of issues I was work-arounding before
-
-	* libgksu/gksu-context.c:
-	- fixed password checking to correct number of chars to compare
-	  and close fdpty after the comparison so su will not be blocked
-	  trying to write to the terminal
-
-	* libgksu/gksu-context.c:
-	- avoid using the keyring if su will simply work without
-	  a password or if the password is not there at the time
-	  it needs to be saved
-	- nullify the password when entering try_need_password
-	  and if su will run without it (it may have been reset
-	  by try_gnome_keyring)
-
-	* libgksu/gksu-context.c:
-	- implemented a new test to simply try to run su and
-	  see what happens to check if we need a password
-	- the above involved some changes to the _run method
-	  so it won't simply bail out if a password is not
-	  supplied and will also be more careful while discarting
-	  su output, which will simply not exist in some cases
-
-2005-06-16  Gustavo Noronha Silva  <kov at debian.org>
-
-	* ligbksu/gksu-context.c:
-	- only save the password in the GNOME keyring if try_need_password
-	  has been called
-
-2005-06-15  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/test-gksu.c:
-	- use the new API function for testing if a sudo password
-	  is needed
-	- accept --su and --sudo arguments to try only su or sudo
-	  respectively
-
-	* libgksu/gksu-context.{c,h}:
-	- added a gksu_context_sudo_try_need_password to
-	  pre-check if we need a password; this uses sudo -v
-	  for now but will incorporate other ways of doing the
-	  check soon
-
-2005-06-14  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added ro to ALL_LINGUAS
-
-2005-06-13  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.3.0
-
-2005-06-09  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac, libgksu/Makefile.am:
-	- changes based on the patch by Szilard Novaki to provide a
-	  --enable-gnome-keyring option to configure, disabled by
-	  default
-	- new development version (1.3.0), API/ABI will not really be
-	  guaranteed to be that stable from now on 'till 1.4
-
-	* docs/libgksu1.2-sections.txt:
-	- updated so that the new public API function will appear
-	  in the documentation
-
-	* libgksu/gksu-context.{c,h}:
-	- added new public API function gksu_context_try_need_pass
-	  to check if we need to request a password
-	  (API version went up to 0:1:0, keeping compatibility)
-	- implemented a method of getting a password from and saving 
-	  it to the gnome-keyring, based on a patch provided to
-	  gksu by Szilard Novaki <novaki at agmen-software.com>
-
-2005-06-01  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added eu to ALL_LINGUAS
-
-2005-05-14  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added sk and nl to ALL_LINGUAS
-
-2005-05-13  Miroslav Kure <kurem at debian.cz>
-
-        * configure.ac:
-        - added cs to ALL_LINGUAS
-
-2005-05-12  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added pl to ALL_LINGUAS
-
-2005-05-07  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.c:
-	- accepted patch by Michael Vogt <mvogt at acm.org> to make the
-	  process which uses libgksu the session leader
-
-2005-04-27  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added hu to ALL_LINGUAS
-
-	* configure.ac:
-	- renamed no_NB to nb on ALL_LINGUAS
-
-2005-04-05  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.2.6
-
-	* libgksu/gksu-context.c:
-	- use other tatic to grab xauth cookie to make XDM and
-	  remote users happy. Should address Debian bugs #280914
-	  and #245092.
-
-	* libgksu/gksu-context.c:
-	- applied patch from Michael Vogt to have correct perms
-	  on the .Xauthority file that is created for sudo
-
-	* libgksu/gksu-context.c:
-	- some code cleanup and minor glitches were fixed
-
-	* libgksu/gksu-run-helper.c:
-	- changes to set XAUTHORITY in a more sane way and
-	  call the real command separately
-
-2004-10-17  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.2.5a
-
-	* libgksu/gksu-context.c:
-	- (gksu_context_sudo_run): added some more debugging stuff 
-	  and fixed aditional space when checking if GNOME_SUDO_PASS 
-	  was received, now sudo functionality works again.
-	- (gksu_context_sudo_run): find out if password failed
-
-2004-10-16  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.2.5
-
-	* libgksu/gksu-context.c:
-	- (gksu_context_run): ignore first line when reading the 
-	  output of gksu-run-helper - this should fix Debian bug 
-	  #272133
-	- (gksu_context_sudo_run): fixed the command building
-	  so that -H will only be used if context->keep_env is
-	  set - fixes Debian bug #276720
-
-2004-10-14  Gustavo Noronha Silva  <kov at debian.org>
-
-	* ChangeLog:
-	- converted to UTF-8
-
-	* libgksu/gksu-context.c:
-	- prepare_xauth was modified to always get what comes after
-	  the ':' character, even if context->ssh_fwd is not set,
-	  thus making this variable unused for now... this probably
-	  fixed Debian bug #273819
-
-	* configure.ac:
-	- added no_NB to ALL_LINGUAS
-
-2004-09-07  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.2.4
-
-	* libgksu/gksu-context.c:
-	- applied patch by Martin Pitt <martin.pitt at canonical.com>
-	  to fix buffer overflows
-
-2004-08-15  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.2.3
-
-	* configure.ac:
-	- added ca to ALL_LINGUAS
-
-2004-06-24  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.2.2
-
-	* libgksu/gksu-context.h:
-	- added missing G_END_DECLS to fix C++ pre-processing
-	  (Debian bug #255607)
-
-2004-05-29  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.2.1
-
-2004-05-27  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.ver, libgksu/Makefile.am:
-	- build the library with versioned symbols (thanks
-	  to Steve Langasek's [vorlon's] talk on "Escaping
-	  the dependency hell" at Debian Conference 4
-
-2004-05-18  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.2.0!
-
-	* libgksu/gksu-context.c:
-	- fixed string about Xauthority file already existing
-	  when being created for the target user
-
-	* docs/libgksu-sections.txt:
-	- removed the macros and the get_type function,
-	  added gksu_context_free
-
-	* libgksu/gksu-context.{c,h}:
-	- document GksuContext and gksu_context_free
-
-2004-05-05  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.1.5
-
-	* libgksu/gksu-context.{c,h}:
-	- new error for xauth stuff problems
-	- now gksu looks at the XAUTHORITY environment
-	  variable to get the source from which to copy
-	  the Xauthorization file.
-
-2004-04-11  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.c:
-	- more select->sleep to fix bugs in linux 2.6
-
-2004-03-28  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/test-gksu.c:
-	- changed the command that is called from ls to
-	  xterm
-
-	* libgksu/gksu-context.c:
-	- remove the password displaying debug stuff
-	  (it is not safe ;))
-	- add an usleep to wait 200 usecs on each loop
-	  on the while that prints messages... it seems
-	  like linux 2.6's select() does not want to
-	  wait =)
-
-2004-03-27  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-context.c:
-	- added some wait time before sending the
-	  password to su - the password was not
-	  being sent correctly without this.
-
-2004-03-21  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu.h, gksu-context.h:
-	- changed double quotes to <> in gksu.h,
-	  fixed double inclusion of glib.h and
-	  self-inclusion on gksu-context.h, thanks
-	  to Max Reinhold Jahnke for the later fix
-
-2004-03-19  Gustavo Noronha Silva  <kov at debian.org>
-
-	* COPYING, libgksu/*:
-	- change license to LGPL version 2
-
-2004-03-08  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-main*, libgksu/gksu-context*:
-	- moved -main stuff to -context, made the _run
-	  stuff be methods of the GksuContext object
-	  also wrote a get_type function to the enum
-	  to help bindings
-
-	* libgksu/gksu-context.{h,c}:
-	- removed title, message and icon related methods
-	  as they are now to be used with the gksuui-dialog
-	  widget available in libgksuui
-	- fixed problems with the naming of the GObject-related
-	  macros, so for example TYPE_GKSU_CONTEXT becomes
-	  GKSU_TYPE_CONTEXT -> I had misunderstood the docs and
-	  this seems to confuse the python binding generator
-
-2004-03-07  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/*:
-	- loads of reorganization and code fixing to have
-	  it support the new build system, etc
-
-	* separating libgksu into its own source package
-
-2004-03-05  gettextize  <bug-gnu-gettext at gnu.org>
-
-	* Makefile.am (SUBDIRS): Add intl.
-	(DIST_SUBDIRS): Add intl.
-	* configure.ac (AC_CONFIG_FILES): Add intl/Makefile.
-
-2004-03-05  gettextize  <bug-gnu-gettext at gnu.org>
-
-	* Makefile.am (SUBDIRS): Add m4.
-	(DIST_SUBDIRS): Add m4.
-	(EXTRA_DIST): New variable.
-	* configure.ac (AC_CONFIG_FILES): Add m4/Makefile.
-	(AM_GNU_GETTEXT_VERSION): Bump to 0.14.1.
-
-2004-02-03  Gustavo Noronha Silva  <kov at debian.org> [1.1.1]
-
-	* configure.ac:
-	- polished a bit
-
-	* libgksu/gksu-private.c:
-	- fixed wrong error checking (duh)
-
-	* libgksu/gksu-context.[ch]:
-	- new implementation of GksuContext, based on
-	  the GObject glib facility
-
-	* libgksu/libgksu.c, gksu/gksu.c:
-	- port to the new GObject-based GksuContext
-
-2004-02-02  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/gksu-private.c, libgksu-gksu-private.h:
-	- added a gksu_init_check function to init
-	  gtk
-
-	* libgksu/libgksu.c, libgksu/gksu.h:
-	- added printf-like format support for title and
-	  message setters
-	- call gksu_init_check on all the three main functions
-	  to make sure gtk will be inited
-
-2004-01-29  Gustavo Noronha Silva  <kov at debian.org>
-
-	* gksu/gksu.c:
-	- ported to the new API
-
-	* libgksu/libgksu.c, libgksu/gksu-private.c:
-	- more well-defined separation between exported
-	  and not export symbols (now even using the
-	  visibility __attribute__)
-	- new API, based on contexts, preparation for
-	  1.2
-
-	* gksu/gksuexec.c:
-	- accepted patch from Jorgen Viksell <jorgen.viksell at telia.com>
-	  to have gksuexec show a combo listing all the users on the
-	  system, thanks!
-
-2004-01-20  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.0.3
-
-	* libgksu/libgksu.c:
-	- fixed _gksu_conf->dir allocation for gksu_sudo_run
-	  to work
-
-	* libgksu/libgksu.c:
-	- added aditional error checking code to the xauth
-	  exec to avoid a segfault when it returns nothing
-	  patch by Doug Holland <meldroc at frii.com>
-
-2004-01-18  Gustavo Noronha Silva  <kov at debian.org>
-
-	* gksu/gksu.c, Makefile.am:
-	- added support to sudo, when called as 'gksudo'
-	- create the symlink on install
-
-2004-01-17  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.0.2
-
-2004-01-16  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c, libgksu/gksu.h:
-	- improved error checking
-	- improved error reporting on sudo related stuff
-	- added gksu_sudo_run, with sudo support
-
-	* remove the common directory and library, integrate
-	  the relevant parts into libgksu and gksu separately
-
-	* libgksu/libgksu.c, common/gksutils.c:
-	- incorporated code from gnome-sudo with some
-	  modifications to have gksu handle sudo, too
-	  untested, probably unstable code, needs testing
-	  to be exposed
-
-	* libgksu/Makefile.am:
-	- build the library with -fPIC, to allow prelinking
-
-	* configure.ac:
-	- added da to ALL_LINGUAS
-
-2004-01-15  Gustavo Noronha Silva  <kov at debian.org>
-
-	* libgksu/libgksu.c:
-	- Fixed problems with gksu closing the application
-	  when canceled
-	- gtk_init_check instead of gtk_init, to avoid failures
-	  killing the "parent" application	
-
-2004-01-14  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.0.1
-
-	* Major update on the documentation stuff
-
-	* Small corrections to the locale handling code
-
-2003-12-19  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 1.0.0
-
-	* introducing libgksu! I believe the code is stable
-	  enough for a 1.0 release -- althought the change to
-	  a library might be a big move, the code has not
-	  being changed a lot... let's see if the Debian
-	  unstable trial proves me wrong.
-
-2003-11-18  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.18
-
-	* src/gui.c:
-	- does not quit when grab fails, warns and continues...
-
-	* po/de.po:
-	- small fix, thanks to Michael Vogt <mvogt at acm.org>
-
-	* src/gksu-run-helper.c:
-	- fix bashism
-
-2003-11-14  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.17
-
-	* autogen.sh:
-	- use automake 1.7, instead of 1.6
-
-	* configure.ac, po/pl.po: 
-	- added polish translation, thanks to Emil <emil5 at go2.pl>
-
-	* src/gksu-run-helper.c:
-	- added, to help fix the stupid security bug
-
-	* src/gksu.{c,h}, src/su.c, src/xauth.c:
-	- modified to use the gksu-run-helper, which will
-	  fix the security bug in which the Xauth token
-	  appears on a ps auxwww
-
-2003-08-28  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.16
-
-2003-08-26  Gustavo Noronha Silva  <kov at debian.org>
-
-	* src/xauth.c:
-	- take care to take the MIT-MAGIC-COOKIE-1 from
-	  xauth list, XDM auth strings were biting gksu
-
-2003-08-08  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.15
-
-2003-08-06  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac:
-	- added 'de' (German) to ALL_LINGUAS
-
-	* gksu.desktop, gksuexec.desktop:
-	- added German translation, thanks to:
-	  Sebastian Heinlein <sebastian.heinlein at campus.lmu.de>
-
-2003-07-29  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.14
-
-	* src/su.c:
-	- shows a nicer dialog with 'Wrong password.'
-	  instead of simply 'Child exited with error
-	  1' thingy if su returns 'Authentication failure'
-
-	* src/su.c:
-	- use >& to redirect instead of 2>&1 to make
-	  non-bash shells happy (Closes: #203386,
-	  #203387)
-
-2003-07-24  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.13
-
-	* README:
-	- some explanations added
-
-	* src/gui.c, src/su.c:
-	- some modifications on the default label that's 
-	  presented explaining why it wants the password,
-	  and in the label behavior, in general
-
-	* src/gksu.c, src/xauth.c:
-	- added --ssh-fwd option, which uses just the :x.x
-	  part of display when working with xauth, for gksu
-	  to work on ssh X11 forwarding 
-	  (Closes Debian bug: #202532)
-
-2003-07-23  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.12
-
-2003-07-22  Gustavo Noronha Silva  <kov at debian.org>
-
-	* src/xauth.c:
-	- added output about xauth token, file, directory and
-	  display, for debuging purposes (when --debug is enabled)
-	- fixed clean_dir to remove the directory if it is empty
-	  before clean_dir is called
-
-	* src/su.c:
-	- do not show xauth's output, unless --debug is given
-	- get rid of bashism when calling xauth by using the
-	  env command
-
-	* src/gksu.c:
-	- added a --debug option, to ask for more verbose
-	  output
-
-2003-07-14  Gustavo Noronha Silva  <kov at debian.org>
-
-	* man/gksu.1:
-	- fixed --icon position
-
-2003-06-14  gettextize  <bug-gnu-gettext at gnu.org>
-
-	* Makefile.am (ACLOCAL_AMFLAGS): New variable.
-	* configure.ac (AC_CONFIG_FILES): Add m4/Makefile.
-	(AM_GNU_GETTEXT_VERSION): Bump to 0.12.1.
-
-2003-06-14  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.11
-
-	* Applied patch from Álvaro Peña <apg at esware.com>
-	  to HIG-ify gksu a bit more
-
-2003-05-24  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.10
-
-	* src/su.c:
-	- Why the hell do I want gksu to automaticaly go to
-	  background? Changed that, I guess that'll help
-	  lots of scripts.
-
-2003-05-10  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.9
-
-	* src/gksuexec.c:
-	- fixed the way the command is passed as argument
-	  to gksu to fix running programs with arguments (duh)
-
-2003-05-08  Gustavo Noronha Silva  <kov at debian.org>
-
-	* src/su.c:
-	- fixed bug which did not allow gksu to run programs
-	  with arguments like, say, 'emacs /etc/mozpluggerrc' =)
-
-2003-05-06  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac: added es.po to ALL_LINGUAS
-
-2003-05-02  Gustavo Noronha Silva  <kov at debian.org>
-
-	* configure.ac: added ru.po to ALL_LINGUAS
-
-2003-04-05  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.8
-
-	* src/xauth.c:
-	- initialize 'xauth' to avoid problems with junk
-	  thanks to Alex Stewart <am2stewa at uwaterloo.ca>
-
-	* src/gui.c:
-	- wait a bit longer before checking for the effectiveness of
-	  the keyboard/mouse grab
-
-2003-03-29  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.7
-
-	* src/gksu.c, src/xauth.c:
-	- remove references to sudo, at least for now
-
-	* src/sudo.{c,h}:
-	- removed, no longer provide sudo functionality, it
-	  doesn't work as well as it should
-
-2003-03-28  Gustavo Noronha Silva  <kov at debian.org>
-
-	* src/su.c:
-	- use xauth information to make the magic work
-
-	* src/xauth.c:
-	- implement prepare_xauth_su to handle Xauth in a safer way,
-	  by using the 'xauth' program instead of a world readable
-	  .Xauthorization file
-	- move the old way of doing things to the prepare_xauth_sudo
-	  function... sudo is a difficult piece of software to handle
-
-	* src/gksu.c:
-	- moved as much xauth specific stuff as I could to xauth.c
-
-2003-02-01  Allan Douglas  <allan_douglas at gmx.net>
-
-	* src/sudo.c:
-	- cleanups
-	
-2003-01-31  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.1
-
-	* AUTHORS:
-	- added Allan Douglas
-
-2003-01-31  Allan Douglas  <allan_douglas at gmx.net>
-
-	* src/su.c:
-	- fixed the "missing output" bug
-
-2003-01-30  Allan Douglas  <allan_douglas at gmx.net>
-
-	* configure.ac:
-	- removed yacc dependency
-
-	* src/su.c:
-	- cleanups
-
-2003-01-30 Gustavo Noronha Silva   <kov at debian.org>
-
-	* src/su.c, src/sudo.c: 
-	- fixed some stuff pointed by my friend "o_0" =P
-
-	* src/gksuexec.c:
-	- has an 'advanced' dialog to select options
-	'login_shell' and '--preserv-env' for gksu
-
-2003-01-30  Gustavo Noronha Silva  <kov at debian.org>
-
-	* src/gksuexec.c:
-	- has an 'advanced' dialog to select options
-	  'login_shell' and '--preserv-env' for gksu
-
-2003-01-29  Gustavo Noronha Silva  <kov at debian.org>
-
-	* man/gksu.1:
-	- added reference for gksuexec command
-	- updated with the help of the 'help2man' command
-
-	* man/gksuexec.1: (new)
-	- wrote manpage to the new command
-
-	* man/Makefile.am: (new)
-	- install manpages
-
-	* src/gksu.c:
-	- fixed small and harmless segfault when free'ing
-	  conf.title
-	- accept -i, --icon to set window's icon
-	- print-pass' message no longer assumes root user
-
-	* src/gui.c:
-	- use gksu's icon at the window, instead of the
-	  question mark
-	- use conf.icon to set gksu window's icon
-
-2003-01-29  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.9.0
-
-	* src/gksuexec.c:
-	- a new program, a dialog to ask for other informations
-	  as a wrapper to gksu's command line
-
-	* src/util.{c,h}, src/gui.{c,h}:
-	- moved gk_dialog from gui to util to make it easier
-	  for gksuexec to use it
-
-	* gksuexec.desktop:
-	- new icon for GNOME, to run gksuexec
-
-2003-01-28  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.8.5
-
-	* src/su.c:
-	- does not ask for password when the real uid
-	  is 0 (see http://bugs.debian.org/178675)
-
-	* src/gksu.c:
-	- minor aesthetical fixes
-
-2003-01-22  Gustavo Noronha Silva  <kov at debian.org>
-
-	* Release 0.8.4
-
-2003-01-14  Gustavo Noronha Silva  <kov at debian.org>
-
-	* src/Makefile.am:
-	- define DATA_DIR
-	- add optimization on compilation
-
-	* src/gui.c:
-	- set default windows icon (requires Gtk+2.2)
-
-	* gksu.png:
-	- new icon, from art.gnome.org, Authorization.png
-
-	* gksu.png -> gksu-terminal.png:
-	- renamed icon for gnome's desktop icon
-
-2003-01-14  Gustavo Noronha Silva  <kov at debian.org>
-
-	* 0.8.3 Release
-
-	* clean up to the build system, using autoconf
-	  2.50 and automake-1.6
-
-	* man/gksu.1:
-	- fixed WHATIS entry
-
-	* gksu.desktop, gksu.png:
-	- icon for GNOME's System menu, to open a terminal
-	  as the root user
-
-2003-01-14  Gustavo Noronha Silva  <kov at debian.org>
-
-	* 0.8.2 Release
-	- changed configure.in
-
-	* src/gksu.c:
-	- make reset environment the default, changed:
-	  reset-env, r to preserv-env, k
-	- make not login shell the default, again, it
-	  will make the Xauth stuff break... duh
-
-	* src/su.c, src/sudo.c:
-	- yes, yes, auto-background again =P
-
-	* src/gui.c:
-	- cleans the Xauth directory in case the dialog is
-	  canceled or closed
-	- changed buttons' positions to reflect the changes
-	  that happened to GNOME2
-
-	* src/gksu.c:
-	- made title more i18n friendly, fixed some small
-	  memory leaks
-
-	* po/pt_BR.po:
-	- updated translation
-
-2003-01-12  Gustavo Noronha Silva  <kov at debian.org>
-
-	* src/gksu.c:
-	- make login shell by default
-
-	* src/su.c, src/sudo.c:
-	- no grandchild, no auto-background anymore
-	- fixes on outputing things
-
-2002-08-13  gettextize  <bug-gnu-gettext at gnu.org>
-
-	* Makefile.am (SUBDIRS): Add m4.
-	(SUBDIRS): Remove intl.
-	(ACLOCAL_AMFLAGS): New variable.
-	(EXTRA_DIST): New variable.
-
-	* configure.in (AC_OUTPUT): Add m4/Makefile.
-
-2002-02-18  Gustavo Noronha Silva  <kov at debian.org>
-
-	* gksu: initial version.
-

Copied: libgksu/tags/2.0.9/ChangeLog (from rev 847, libgksu/trunk/ChangeLog)
===================================================================
--- libgksu/tags/2.0.9/ChangeLog	                        (rev 0)
+++ libgksu/tags/2.0.9/ChangeLog	2009-03-04 18:55:14 UTC (rev 848)
@@ -0,0 +1,1543 @@
+2009-03-04  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 2.0.9
+
+	* libgksu/libgksu.c: fix how the GdkDisplay* is obtained at
+	gksu_context_launch_initiate
+
+	* libgksu/gksu-run-helper.c: - cleanup the environment from
+	ORBIT_SOCKETDIR and DBUS_SESSION_BUS_ADDRESS to acommodate recent
+	changes in gconf
+
+2009-02-22  Gustavo Noronha Silva  <kov at alface>
+
+	* Release 2.0.8
+
+2009-02-22  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c: - added threads protection for the gdk
+	fadeout/fadein animation, so that callers will not have X errors
+	when trying to use gdk functions in parallel with us
+	See http://bugzilla.gnome.org/show_bug.cgi?id=549760.
+
+2009-02-22  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac, libgksu/libgksu.{c,h}, libgksu/gksu-run-helper.c:
+	- accepted patch by Joshua Kwan <jkwan at vmware.com> to
+	  return the same status code as the child
+
+2009-02-03  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added th to ALL_LINGUAS
+
+2008-08-29  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c: patch by Daniel Richard G. <skunk at iSKUNK.ORG>
+	to allow changing the location of the lockfile, so that libgksu
+	will work on AFS/NFS mounted home directories
+
+2008-06-20  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-run-helper.c: accepted patch by Michael Vogt, from
+	Ubuntu, to fix very long commands not fitting in the helper's
+	statically-sized buffer (Debian bug #486087, launchpad #173757)
+
+	* libgksu/libgksu.c (sudo_full): accepted patch by Michael Vogt,
+	from Ubuntu, to fix sudo having problems resolving network
+	addresses breaking gksu (Debian bug #486083, launchpad #237325)
+
+2008-05-27  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 2.0.7
+
+	* libgksu/libgksu.c (gksu_sudo_full): accepted patch by Ben
+	Hutchings <ben at decadent.org.uk> to also disable nonblocking I/O
+	when no password is asked (Debian bug #463709)
+
+	* configure.ac: - remove \n from the test code used to test for
+	the presence of the -version-script linker option; that was
+	causing the test to fail
+
+2008-05-16  Gustavo Noronha Silva  <Gustavo Noronha Silva <kov at alfaiati.net>>
+
+	* Release 2.0.6
+
+2008-01-02  Guilherme de S. Pastore  <gpastore at debian.org>
+
+	* libgksu/libgksu.c (gksu_sudo_full): fix typo introduced with the latest
+	  changes ("aways").
+
+2007-12-31  Gustavo Noronha Silva  <kov at cenoura>
+
+	* libgksu/libgksu.c:
+	- format parameters were wrong for the case in which you
+	  ask gksu to run a given command as a given user (other than
+	  root); thanks to Uwe Kleine-König <ukleinek at informatik.uni-freiburg.de>
+	  for pointing out; Debian bug #449180
+
+	* libgksu/libgksu.c:
+	- accepted patch from Ubuntu by Michael Vogt to add a new
+	  property for GksuContext: always_ask_password; the patch
+	  suffered minor aditions by me to also implement the functionality
+	  to the su backend and document the limitations (Debian bug #453423)
+
+	* libgksuui/gksuui-dialog.c:
+	- accepted patch from Ubuntu by Michael Vogt that fixes
+	  the capslock notification so that it doesn't change the
+	  size of the window (Debian bug #453426)
+
+2007-06-22  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- accepted patch from Ubuntu, by Michael Vogt, that
+	  fixes the way gksu waits for the child process to
+	  finish; see:
+	https://bugs.launchpad.net/ubuntu/+source/libgksu/+bug/121581
+
+2007-06-10  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 2.0.5
+
+	* libgksu/libgksu.c:
+	- also complete launch notification when cancel is
+	  pressed in the dialog; (Addressing Debian Bug #426495)
+
+2007-06-09  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- reworked the way gksu_su{,do}_full relays the child's
+	  output, making it sleep rather than wakeup every
+	  few microseconds (Addressing Debian Bug #425679)
+
+2007-05-11  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added sv and zh_CN.po to ALL_LINGUAS
+
+2007-03-28  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added ko to ALL_LINGUAS
+
+2007-03-06  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- always try to create the keyring when setting the password;
+	  if the keyring exists this is a no-op, so no problems
+	  (Addressing Debian Bug #412681)
+
+	* libgksu/libgksu.c:
+	- improved debugging for getting the password from the
+	  GNOME Keyring; and do not show the password anymore when
+	  debugging
+
+2007-03-04  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- accepted patch by Michael Vogt to handle the
+	  better quoted strings given by gksu
+
+2007-02-04  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 2.0.4
+
+2007-01-22  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.[ch]:
+	- accepted patch by "Gian Mario Tagliaretti"
+	  <g.tagliaretti at gmail.com> to turn GksuContext into
+	  a boxed type, so that it can be used in a saner way
+	  in bindings
+
+2007-01-05  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- accepted patch by Виталий Ищенко <betalb at gmail.com>
+	  which makes libgksu only replace the 'password typing' character
+	  when '*' is the default one
+
+2006-12-07  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- make sure DESKTOP_STARTUP_ID is set in the environment correctly
+
+2006-10-31  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- remove a trailing \n if it exists in the password we get from
+	  the GNOME Keyring (Addresses Debian Bug #395462)
+
+2006-10-23  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 2.0.3
+
+	* libgksu/libgksu.c:
+	- make sure the dialog is _destroyed_ instead of just being
+	  hidden, after some action has been taken in the dialog that
+	  asks for the password
+	- returns WRONGAUTOPASS instead of WRONGPASS when wrong password
+	  is the one we got from the gnome keyring
+	- store the password in the GNOME Keyring without the \n
+	  (Addresses Debian Bug #394895)
+
+2006-10-22  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 2.0.2
+
+	* libgksu/libgksu.c:
+	- make sure we notice ECHO disabled, and remove some uneeded waits
+	  which will probably speedup using su with password, but probably
+	  slow down su without password; this should avoid deadlocks when
+	  su delays setting ECHO off.
+
+2006-10-15  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksuui/gksuui-dialog.c:
+	- try to always have focus, by traping the focus-out-event;
+	  should address Debian bug #391804
+
+2006-10-08  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 2.0.1
+
+	* libgksu/libgksu.c:
+	- use some brute force reading when using sudo, to be able
+	  to handle stuff like the sudo lecture and pam modules debugging
+
+2006-10-01  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- if xauth is an empty string when using the su backend,
+	  then try to get it again by striping the hostname part
+	  of the display string; this is needed for ssh X forwarding
+
+2006-09-23  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- version set to 2.0.0; releasing libgksu 2, at last!
+
+2006-09-07  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- have gksu ignore lines coming from the process 'till it is able
+	  to find the gksu: waiting line; this is done observing some
+	  time and size constraints, though, so we won't end up in an infinite
+	  loop; this addresses #17139; libpam-mount should now work happily with
+	  debug on
+	- also make su's child session leader, like sudo's, so that when the
+	  program you ran launches another, closing the first will not destroy
+	  the second
+
+2006-09-02  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added it to ALL_LINGUAS
+
+2006-08-19  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added lt to ALL_LINGUAS
+
+	* libgksu/libgksu.c:
+	- add gettext call in the prompt in su_ask_password, so that
+	  the prompt is translated
+
+2006-08-15  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- accepted patch by Michael Vogt to fix the detection of
+	  sudo password failure by making the fd block while expecting
+	  the line right after the password is sent to sudo
+
+2006-08-06  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.9.8
+
+	* libgksu/libgksu.c:
+	- bring the rest of the startup notification code from the
+	  application
+
+2006-07-19  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.9.7
+
+	* libgksuui/gksuui-dialog.{c,h}:
+	- gksuui_dialog_init is not called after the properties
+	  are set, so post-pone creating the gnome-keyring UI
+	  when they are; also fixes a logic error
+
+2006-07-16  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.9.6
+
+	* libgksuui/gksuui-dialog.c, libgksu/libgksu.c:
+	- add a new object property to GksuuiDialog, and pass
+	  the sudo_mode boolean to it on object instanciation,
+	  so that the sudo window will not have the gnome_keyring
+	  stuff, again
+
+	* libgksu/libgksu.c[gksu_sudo_full]:
+	- use select in the read side of the parent_pipe, so that
+	  the sudo prompt will not show up after the non-blocking
+	  read is done (addresses Debian bug #377746)
+	- do not remove the hostname/socket part of the DISPLAY
+	  (addresses Debian bug #349652)
+
+2006-07-12  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.9.5
+
+	* libgksu/libgksu.{c,h}:
+	- add accessor methods for the startup notification launcher
+	  context
+
+2006-07-10  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- increment version to 1.9.5
+
+	* libgksu/libgksu.{c,h}, libgksuui/gksu-dialog.{c,h}:
+	- implement a new 'alert' label, to allow applications showing
+	  messages like 'wrong password, try again'
+
+2006-07-05  Gustavo Noronha Silva  <kov at debian.org>
+
+	* gksu.png, gksu-properties/{Makefile.am,gksu-properties.desktop.in,
+	  gksu-properties.c}:
+	- added an icon, and a desktop file so that the capplet will show in
+	  the preferences menu for the desktop
+
+2006-07-03  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- remove \n from the check of the command name, since gtop
+	  does not give a \n-terminated string; thanks to
+	  Benoît Dejean <benoit at placenet.org> for pointing this out
+
+2006-06-29  Gustavo Noronha Silva  <kov at debian.org>
+
+	* gksu-properties/*:
+	- start a simple capplet to configure the gksu gconf
+	  preferences
+
+	* libgksu/defines.h:
+	- small adaption so it can better be used by gksu-properties
+
+2006-06-26  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.9.4
+
+	* libgksu/libgksu.c:
+	- correctly derreference the error pointer when checking
+	  if something was returned by ask_pass
+
+2006-06-25  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.9.3
+
+	* libgksu/libgksu.c:
+	- use TRUE for success and FALSE for failure, to match glib's
+	  spawn API - well, it's a development release =D
+
+	* libgksu/libgksu.c:
+	- handle canceling the dialog correctly; added a new
+	  error to the enum
+
+	* configure.ac, libgksu/libgksu.c:
+	- accepted patch by Benoît Dejean <benoit at placenet.org>
+	  to get the process name in a platform independent way
+
+2006-05-01  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added fr to ALL_LINGUAS
+
+	* configure.ac, libgksu/Makefile.am:
+	- only use the version script if the system we're
+	  building on supports it; thanks to Daniel Macks
+	  for the patch
+
+	* libgksu/libgksu.c:
+	- check fread's return value before using strlen
+	  and setting a \0 in the xauth string, to prevent
+	  problems when xauth returns nothing (#7698)
+	- handle locales which mess with the 'su:' layout
+
+	* Release 1.9.2
+
+	* configure.ac:
+	- fixed gettext domain define
+
+2006-04-30  Gustavo Noronha Silva  <kov at debian.org>
+
+	* docs/*:
+	- updated documentation
+
+	* libgksu/Makefile.am:
+	- increased minor version of the library, since some
+	  symbols were added
+
+	* libgksuui/Makefile.am:
+	- do not build a static version of the lib only;
+	  I need a shared version with PIC symbols built so
+	  that libgksu will be able to be fully PIC
+
+	* libgksu/libgksu.c:
+	- provide an API for simply getting the password
+	- standardize the get methods that return string to
+	  return NULL if they were not set, and updated
+	  "docstrings" to fit;
+	- removed translatable marks for strings that are
+	  errors printed to stderr
+	- made some strings look better or more HIG compliant
+
+	* libgksuui/libgksu.{c,h}, libgksuui/gksuui-dialog.c:
+	- accepted changes from the Ubuntu people to make the dialog
+	  and messages be more beatiful; also provide an API that
+	  enables specifying a descriptional name for the command, that
+	  is used automatically in the message
+
+	* libgksuui/gksuui-dialog.c:
+	- do not center the label that is used to display
+	  the message
+
+2006-04-24  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- use the internal context->sudo_mode to tell the
+	  ask_pass function if we're on su or sudo mode
+
+	* libgksu/libgksu.{c.h}:
+	- implemented the message setting and getting
+	  functions, and use the message that is given
+	  when creating the dialog
+
+	* Release 1.9.1
+
+2006-04-23  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu2.pc.in:
+	- add gnome-keyring-1 and gconf-2.0 as dependencies
+
+	* Release 1.9.0
+
+	* libgksu/test-gksu.c:
+	- display message before testing gksu_sudo_full, so we
+	  get a better picture of where stuff is happening
+	- add a test to the new gksu_run{,_full} API
+
+	* libgksu.c:
+	- use non-blocking read when looking for the sudo prompt,
+	  so that we won't get blocked if there is none; also,
+	  make sure the window is displayed
+	- (su) track that gnome keyring was used to enhance the pass_not_needed
+	  display logic; display it parallel to running the command, to match
+	  gksu_sudo_full behavior
+	- only print the password when on debug mode
+	- init sn_context with NULL, so non-SN-supporting users will
+	  not segfault when we check for the value
+
+	* libgksu/libgksu.{c,h}:
+	- new API gksu_run{,_full}, that is a generic way of using
+	  gksu functionality, leaving the choice of su or sudo backend
+	  to the gconf setting
+
+2006-04-16  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- used suggestion by Benoît Dejean <benoit at placenet.org>
+	  to avoid buffer overflows on the debug code
+
+	* libgksu/libgksu.c:
+	- patch from Michael Vogt to fix corner condition which
+	  happens when fgets returns badly with a specific app
+
+2006-04-15  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c, libgksu/gksu-run-helper.c:
+	- check for xauth at /usr/bin (Xorg 7.0) and /usr/X11R6/bin
+	  (Xorg 6.9 and XFree86) [merged from trunk]
+
+2006-03-12  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksuui/gksuui-dialog.c:
+	- added UI for the gnome-keyring support in the main widget
+
+	* libgksu/libgksu.c:
+	- Preliminary support for gnome-keyring imported from the
+	  gksu app code; it now removes the password from the
+	  keyring in case it tries with it and fails
+
+2006-03-02  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added dependency on libstartup-notification-1.0 to
+	  PKG_CHECK_MODULES; startup notification support has
+	  been added!
+
+	* libgksu/test-gksu.c:
+	- use the new location for xterm (FHS-compliant)
+
+	* libgksu/libgksu.c:
+	- integrated patch by Michael Vogt to support startup notfication
+	- added accessor methods for the GksuContext structure, I want it
+	  to be opaque
+
+	* libgksu/Makefile.am, libgksu/libgksu2.pc.in:
+	- misc fixes to build system
+
+2006-01-24  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksuui/gksuui-dialog.{c,h}:
+	- applied patch by Michael Vogt to report that capslock is enabled
+	  with small modifications
+
+2006-01-07  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c, docs/*:
+	- revamp documentation; gtk-doc-style comments added to
+	  functions and some fixes to return values were made to
+	  match the docs
+
+	* configure.ac, Makefile.am, others:
+	- revamping the i18n infra-structure; mainly removing
+	  local intl/ copy and updating files
+	- do not use local copies of m4 files in a m4/ directory
+
+	* configure.ac:
+	- do not create pkg-config files for libgksuui; it won't
+	  be installed anymore
+
+	* Make libgksuui a sub, static library for libgksu only.
+	- removed gksu-convenience stuff, that is not going to
+	  be used anymore
+
+2005-12-11  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Major design overhaul
+	- incorporating libgksuui
+	- no longer try to be UI independent; use GTK+ mercylessly
+	- incorporating gconf schema and settings handling
+	- massive API review, removal of most public functions;
+	  GksuContext is no longer a GObject-based object, no longer
+	  has many accessor functions for its data fields and is
+	  needed for the _full versions of the main API functions
+	  right now; this allows saner handling of password prompting
+	  and housekeeping
+
+	* gksu.schemas.in:
+	- remove always-ask-password for now, it will probably be
+	  replaced by something else when gnome-keyring is integrated
+
+	* intltoolized, modified some stuff for the package
+	  renaming to work
+
+	* libgksu/libgksu.c:
+	- integrated 'prompt before grab' support; also make the
+	  foce-grab configuration effective
+
+	* renaming files:
+	- libgksu/gksu-context.{c,h} -> libgksu/libgksu.{c,h}
+
+2005-11-23  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.3.7
+
+2005-11-17  Gustavo Noronha Silva  <kov at debian.org>
+
+        Following 4 fixes were done with information and help
+	provided by Benoît Dejean <benoit at placenet.org>; thanks!
+
+	* libgksu/gksu-context.c:
+	- change debug message for the case in which we can't find
+	  a password prompt
+
+	* libgksu/gksu-context.c:
+	- do not free the user component of the context struct
+	  twice
+
+	* libgksu/gksu-context.c:
+	- init buffer with {0} so that debuging information will
+	  not show crappy stuff for it
+
+	* libgksu/gksu-context.c:
+	- check if pass_not_needed is there before calling
+	  it on gksu_context_sudo_run_full
+
+2005-10-25  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.3.6
+
+2005-10-02  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.c:
+	- fix logic problem when checking if what was read does not
+	  start with "gksu" or "su" - thanks to Guilherme de S. Pastore
+          for spotting the problematic range of code (Debian bug #331124)
+
+2005-09-29  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.3.5
+
+	* libgksu/gksu-context.c:
+	- fixed some memory leaks which were added by lack of
+	  caution on my part =/
+
+2005-09-28  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.3.4
+
+	* relibtoolized with libtool --automake -c -f
+	  (Debian's libtool 1.5.20-1)
+
+	* configure.ac: bump version to 1.3.4
+
+	* libgksu/gksu-context.c:
+	- apply the same solution to handling error return
+	  checking to the su backend
+
+2005-09-21  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.c:
+	- handle 'not in sudoers' message (Ubuntu's #14922)
+
+2005-09-18  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.c:
+	- applied a patch to use /proc information to find out the
+	  name of the current child process to check if it was sudo
+	  who returned a failure code or the app we called on Linux
+	  systems; patch and modifications done to it were made by
+	  Michael Vogt and his advice, respectively (Ubuntu's #7517)
+
+2005-09-12  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.c:
+	- treat the command line to remove the quotes that may have
+	  been added by gksu's multi-argument processing code
+
+2005-08-20  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.{c,h}:
+	- improve error reporting for sudo; tries to detect if sudo
+	  reported that the user cannot run the command for that user
+
+2005-08-02  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.3.3
+
+	* libgksu/Makefile.am:
+	- undo soname change because I stepped back from breaking the ABI
+
+	* libgksu/gksu-context.{c,h}:
+	- leave ask_and_run as deprecated functions to let software which
+	  used it at some point in development keep building and running
+
+	* libgksu/gksu-context.{c,h}:
+	- replaced ask_and_run with run_full for both su and sudo; the
+	  new API function which accepts another callback function that
+	  allows the user application to do something if a password was
+	  not needed like, for example, warning the user
+
+2005-08-01  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.c, libgksu/Makefile.am, configure.ac:
+	- revert inclusion of gnome-keyring support, which should
+	  actually go into the app, not the lib
+
+2005-07-21  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/Makefile.am:
+	- increased minor version number because of the adition
+	  to the API
+
+	* libgksu/gksu-context.{c,h}, libgksu/test-gksu.c:
+	- implemented the gksu_context_ask_and_run counterpart
+	  for sudo
+
+2005-07-14  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.3.2 - The "Helsinki" Release!
+
+	* libgksu/Makefile.am:
+	- increase library minor version because API was added without
+	  breaking ABI (yet! =D)
+
+	* libgksu/gksu-context.c:
+	- wrap the keyring callback in the ENABLE_GNOME_KEYRING
+	  ifdef
+
+	* libgksu/gksu-context.c, docs/libgksu1.2-sections.txt:
+	- make sure every public API function is documented
+
+	* libgksu/gksu-context.c:
+	- small fixes and improvements to some info and error messages
+
+	* libgksu/gksu-context.c:
+	- handle the droping of the \n echoed after password was given
+	  if a password needed to be given, so we have wheel trust and
+	  other situations in which you don't need a password handled
+	  correctly
+
+2005-07-13  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.c:
+	- kill su in try_su_run instead of simply sending a "\n" if it
+	  asks for password, so we improve speed and avoid dead locks
+
+	* libgksu/gksu-context.c:
+	- after-password conversation with helper improved quite a bit
+	  and made simpler; should fix some problems with gksu-run:
+	  strings coming out eventually and prevent some cases of dead
+	  locks
+
+	* libgksu/gksu-context.c:
+	- accepted patch by Aurelien Jacobs <aurel at gnuage.org> that
+	  moves the keyring_create_item_cb outside of the function
+	  which calls it, so gksu will not segfault on AMD64, which
+	  does not permit execution of the stack; this addresses
+	  Debian bugs #318031, #307975 and #314369.
+
+2005-07-12  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.c:
+	- also use the ECHO trick for try_su_run
+
+	* libgksu/gksu-context.c:
+	- OK, so the call to usleep must be inside the while loop so
+	  gksu won't be eating CPU time
+
+2005-07-11  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/test-gksu.c:
+	- fixed su_ask_pass declaration to include the GError** argument
+
+	* libgksu/gksu-context.c:
+	- init buf on gksu_context_ask_and_run with \0's so we don't get 
+	  random weird stuff at the first time we read something to it
+
+	* libgksu/gksu-context.c:
+	- better checking of whether a prompt is waiting for a password
+	  or not to figure out if a password is needed or not; this enhances
+	  the 'only ask for password if really needed' approach and is one 
+	  more step on addressing Debian's #246652; this required some 
+	  tweaking to the logic used in conversation with gksu-run-helper.
+
+	* libgksu/gksu-context.c:
+	- Fixed wording on xauth warning message so it will not use first
+	  person; this addresses Debian bug #309563.
+
+2005-07-09  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.c:
+	- kill sudo when trying validation and wait a bit before
+	  wait()'ing, so gksu gets blocked for less time
+
+2005-06-29  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.{c,h}:
+	- modified the password-asking function to receive a GError**
+	  so we have the possibility of creating a 'problem reporting'
+	  interface for it
+	- also, check the return value of the function and bail out
+	  if it is FALSE
+
+2005-06-28  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.c:
+	- make a gksu_context_ask_and_run that receives a function
+	  pointer to request password if needed (so you don't have
+	  to fill context->password beforehand)
+	* libgksu/test-gksu.c:
+	- also test the new API function
+
+2005-06-18  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.3.1
+
+	* libgksu/test-gksu.c:
+	- s/strings.h/string.h/
+
+	* libgksu/gksu-context.c:
+	- call try_su_run before the gnome-keyring test; this solves
+	  lots of issues I was work-arounding before
+
+	* libgksu/gksu-context.c:
+	- fixed password checking to correct number of chars to compare
+	  and close fdpty after the comparison so su will not be blocked
+	  trying to write to the terminal
+
+	* libgksu/gksu-context.c:
+	- avoid using the keyring if su will simply work without
+	  a password or if the password is not there at the time
+	  it needs to be saved
+	- nullify the password when entering try_need_password
+	  and if su will run without it (it may have been reset
+	  by try_gnome_keyring)
+
+	* libgksu/gksu-context.c:
+	- implemented a new test to simply try to run su and
+	  see what happens to check if we need a password
+	- the above involved some changes to the _run method
+	  so it won't simply bail out if a password is not
+	  supplied and will also be more careful while discarting
+	  su output, which will simply not exist in some cases
+
+2005-06-16  Gustavo Noronha Silva  <kov at debian.org>
+
+	* ligbksu/gksu-context.c:
+	- only save the password in the GNOME keyring if try_need_password
+	  has been called
+
+2005-06-15  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/test-gksu.c:
+	- use the new API function for testing if a sudo password
+	  is needed
+	- accept --su and --sudo arguments to try only su or sudo
+	  respectively
+
+	* libgksu/gksu-context.{c,h}:
+	- added a gksu_context_sudo_try_need_password to
+	  pre-check if we need a password; this uses sudo -v
+	  for now but will incorporate other ways of doing the
+	  check soon
+
+2005-06-14  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added ro to ALL_LINGUAS
+
+2005-06-13  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.3.0
+
+2005-06-09  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac, libgksu/Makefile.am:
+	- changes based on the patch by Szilard Novaki to provide a
+	  --enable-gnome-keyring option to configure, disabled by
+	  default
+	- new development version (1.3.0), API/ABI will not really be
+	  guaranteed to be that stable from now on 'till 1.4
+
+	* docs/libgksu1.2-sections.txt:
+	- updated so that the new public API function will appear
+	  in the documentation
+
+	* libgksu/gksu-context.{c,h}:
+	- added new public API function gksu_context_try_need_pass
+	  to check if we need to request a password
+	  (API version went up to 0:1:0, keeping compatibility)
+	- implemented a method of getting a password from and saving 
+	  it to the gnome-keyring, based on a patch provided to
+	  gksu by Szilard Novaki <novaki at agmen-software.com>
+
+2005-06-01  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added eu to ALL_LINGUAS
+
+2005-05-14  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added sk and nl to ALL_LINGUAS
+
+2005-05-13  Miroslav Kure <kurem at debian.cz>
+
+        * configure.ac:
+        - added cs to ALL_LINGUAS
+
+2005-05-12  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added pl to ALL_LINGUAS
+
+2005-05-07  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.c:
+	- accepted patch by Michael Vogt <mvogt at acm.org> to make the
+	  process which uses libgksu the session leader
+
+2005-04-27  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added hu to ALL_LINGUAS
+
+	* configure.ac:
+	- renamed no_NB to nb on ALL_LINGUAS
+
+2005-04-05  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.2.6
+
+	* libgksu/gksu-context.c:
+	- use other tatic to grab xauth cookie to make XDM and
+	  remote users happy. Should address Debian bugs #280914
+	  and #245092.
+
+	* libgksu/gksu-context.c:
+	- applied patch from Michael Vogt to have correct perms
+	  on the .Xauthority file that is created for sudo
+
+	* libgksu/gksu-context.c:
+	- some code cleanup and minor glitches were fixed
+
+	* libgksu/gksu-run-helper.c:
+	- changes to set XAUTHORITY in a more sane way and
+	  call the real command separately
+
+2004-10-17  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.2.5a
+
+	* libgksu/gksu-context.c:
+	- (gksu_context_sudo_run): added some more debugging stuff 
+	  and fixed aditional space when checking if GNOME_SUDO_PASS 
+	  was received, now sudo functionality works again.
+	- (gksu_context_sudo_run): find out if password failed
+
+2004-10-16  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.2.5
+
+	* libgksu/gksu-context.c:
+	- (gksu_context_run): ignore first line when reading the 
+	  output of gksu-run-helper - this should fix Debian bug 
+	  #272133
+	- (gksu_context_sudo_run): fixed the command building
+	  so that -H will only be used if context->keep_env is
+	  set - fixes Debian bug #276720
+
+2004-10-14  Gustavo Noronha Silva  <kov at debian.org>
+
+	* ChangeLog:
+	- converted to UTF-8
+
+	* libgksu/gksu-context.c:
+	- prepare_xauth was modified to always get what comes after
+	  the ':' character, even if context->ssh_fwd is not set,
+	  thus making this variable unused for now... this probably
+	  fixed Debian bug #273819
+
+	* configure.ac:
+	- added no_NB to ALL_LINGUAS
+
+2004-09-07  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.2.4
+
+	* libgksu/gksu-context.c:
+	- applied patch by Martin Pitt <martin.pitt at canonical.com>
+	  to fix buffer overflows
+
+2004-08-15  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.2.3
+
+	* configure.ac:
+	- added ca to ALL_LINGUAS
+
+2004-06-24  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.2.2
+
+	* libgksu/gksu-context.h:
+	- added missing G_END_DECLS to fix C++ pre-processing
+	  (Debian bug #255607)
+
+2004-05-29  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.2.1
+
+2004-05-27  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.ver, libgksu/Makefile.am:
+	- build the library with versioned symbols (thanks
+	  to Steve Langasek's [vorlon's] talk on "Escaping
+	  the dependency hell" at Debian Conference 4
+
+2004-05-18  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.2.0!
+
+	* libgksu/gksu-context.c:
+	- fixed string about Xauthority file already existing
+	  when being created for the target user
+
+	* docs/libgksu-sections.txt:
+	- removed the macros and the get_type function,
+	  added gksu_context_free
+
+	* libgksu/gksu-context.{c,h}:
+	- document GksuContext and gksu_context_free
+
+2004-05-05  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.1.5
+
+	* libgksu/gksu-context.{c,h}:
+	- new error for xauth stuff problems
+	- now gksu looks at the XAUTHORITY environment
+	  variable to get the source from which to copy
+	  the Xauthorization file.
+
+2004-04-11  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.c:
+	- more select->sleep to fix bugs in linux 2.6
+
+2004-03-28  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/test-gksu.c:
+	- changed the command that is called from ls to
+	  xterm
+
+	* libgksu/gksu-context.c:
+	- remove the password displaying debug stuff
+	  (it is not safe ;))
+	- add an usleep to wait 200 usecs on each loop
+	  on the while that prints messages... it seems
+	  like linux 2.6's select() does not want to
+	  wait =)
+
+2004-03-27  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-context.c:
+	- added some wait time before sending the
+	  password to su - the password was not
+	  being sent correctly without this.
+
+2004-03-21  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu.h, gksu-context.h:
+	- changed double quotes to <> in gksu.h,
+	  fixed double inclusion of glib.h and
+	  self-inclusion on gksu-context.h, thanks
+	  to Max Reinhold Jahnke for the later fix
+
+2004-03-19  Gustavo Noronha Silva  <kov at debian.org>
+
+	* COPYING, libgksu/*:
+	- change license to LGPL version 2
+
+2004-03-08  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-main*, libgksu/gksu-context*:
+	- moved -main stuff to -context, made the _run
+	  stuff be methods of the GksuContext object
+	  also wrote a get_type function to the enum
+	  to help bindings
+
+	* libgksu/gksu-context.{h,c}:
+	- removed title, message and icon related methods
+	  as they are now to be used with the gksuui-dialog
+	  widget available in libgksuui
+	- fixed problems with the naming of the GObject-related
+	  macros, so for example TYPE_GKSU_CONTEXT becomes
+	  GKSU_TYPE_CONTEXT -> I had misunderstood the docs and
+	  this seems to confuse the python binding generator
+
+2004-03-07  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/*:
+	- loads of reorganization and code fixing to have
+	  it support the new build system, etc
+
+	* separating libgksu into its own source package
+
+2004-03-05  gettextize  <bug-gnu-gettext at gnu.org>
+
+	* Makefile.am (SUBDIRS): Add intl.
+	(DIST_SUBDIRS): Add intl.
+	* configure.ac (AC_CONFIG_FILES): Add intl/Makefile.
+
+2004-03-05  gettextize  <bug-gnu-gettext at gnu.org>
+
+	* Makefile.am (SUBDIRS): Add m4.
+	(DIST_SUBDIRS): Add m4.
+	(EXTRA_DIST): New variable.
+	* configure.ac (AC_CONFIG_FILES): Add m4/Makefile.
+	(AM_GNU_GETTEXT_VERSION): Bump to 0.14.1.
+
+2004-02-03  Gustavo Noronha Silva  <kov at debian.org> [1.1.1]
+
+	* configure.ac:
+	- polished a bit
+
+	* libgksu/gksu-private.c:
+	- fixed wrong error checking (duh)
+
+	* libgksu/gksu-context.[ch]:
+	- new implementation of GksuContext, based on
+	  the GObject glib facility
+
+	* libgksu/libgksu.c, gksu/gksu.c:
+	- port to the new GObject-based GksuContext
+
+2004-02-02  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/gksu-private.c, libgksu-gksu-private.h:
+	- added a gksu_init_check function to init
+	  gtk
+
+	* libgksu/libgksu.c, libgksu/gksu.h:
+	- added printf-like format support for title and
+	  message setters
+	- call gksu_init_check on all the three main functions
+	  to make sure gtk will be inited
+
+2004-01-29  Gustavo Noronha Silva  <kov at debian.org>
+
+	* gksu/gksu.c:
+	- ported to the new API
+
+	* libgksu/libgksu.c, libgksu/gksu-private.c:
+	- more well-defined separation between exported
+	  and not export symbols (now even using the
+	  visibility __attribute__)
+	- new API, based on contexts, preparation for
+	  1.2
+
+	* gksu/gksuexec.c:
+	- accepted patch from Jorgen Viksell <jorgen.viksell at telia.com>
+	  to have gksuexec show a combo listing all the users on the
+	  system, thanks!
+
+2004-01-20  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.0.3
+
+	* libgksu/libgksu.c:
+	- fixed _gksu_conf->dir allocation for gksu_sudo_run
+	  to work
+
+	* libgksu/libgksu.c:
+	- added aditional error checking code to the xauth
+	  exec to avoid a segfault when it returns nothing
+	  patch by Doug Holland <meldroc at frii.com>
+
+2004-01-18  Gustavo Noronha Silva  <kov at debian.org>
+
+	* gksu/gksu.c, Makefile.am:
+	- added support to sudo, when called as 'gksudo'
+	- create the symlink on install
+
+2004-01-17  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.0.2
+
+2004-01-16  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c, libgksu/gksu.h:
+	- improved error checking
+	- improved error reporting on sudo related stuff
+	- added gksu_sudo_run, with sudo support
+
+	* remove the common directory and library, integrate
+	  the relevant parts into libgksu and gksu separately
+
+	* libgksu/libgksu.c, common/gksutils.c:
+	- incorporated code from gnome-sudo with some
+	  modifications to have gksu handle sudo, too
+	  untested, probably unstable code, needs testing
+	  to be exposed
+
+	* libgksu/Makefile.am:
+	- build the library with -fPIC, to allow prelinking
+
+	* configure.ac:
+	- added da to ALL_LINGUAS
+
+2004-01-15  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- Fixed problems with gksu closing the application
+	  when canceled
+	- gtk_init_check instead of gtk_init, to avoid failures
+	  killing the "parent" application	
+
+2004-01-14  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.0.1
+
+	* Major update on the documentation stuff
+
+	* Small corrections to the locale handling code
+
+2003-12-19  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 1.0.0
+
+	* introducing libgksu! I believe the code is stable
+	  enough for a 1.0 release -- althought the change to
+	  a library might be a big move, the code has not
+	  being changed a lot... let's see if the Debian
+	  unstable trial proves me wrong.
+
+2003-11-18  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.18
+
+	* src/gui.c:
+	- does not quit when grab fails, warns and continues...
+
+	* po/de.po:
+	- small fix, thanks to Michael Vogt <mvogt at acm.org>
+
+	* src/gksu-run-helper.c:
+	- fix bashism
+
+2003-11-14  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.17
+
+	* autogen.sh:
+	- use automake 1.7, instead of 1.6
+
+	* configure.ac, po/pl.po: 
+	- added polish translation, thanks to Emil <emil5 at go2.pl>
+
+	* src/gksu-run-helper.c:
+	- added, to help fix the stupid security bug
+
+	* src/gksu.{c,h}, src/su.c, src/xauth.c:
+	- modified to use the gksu-run-helper, which will
+	  fix the security bug in which the Xauth token
+	  appears on a ps auxwww
+
+2003-08-28  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.16
+
+2003-08-26  Gustavo Noronha Silva  <kov at debian.org>
+
+	* src/xauth.c:
+	- take care to take the MIT-MAGIC-COOKIE-1 from
+	  xauth list, XDM auth strings were biting gksu
+
+2003-08-08  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.15
+
+2003-08-06  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac:
+	- added 'de' (German) to ALL_LINGUAS
+
+	* gksu.desktop, gksuexec.desktop:
+	- added German translation, thanks to:
+	  Sebastian Heinlein <sebastian.heinlein at campus.lmu.de>
+
+2003-07-29  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.14
+
+	* src/su.c:
+	- shows a nicer dialog with 'Wrong password.'
+	  instead of simply 'Child exited with error
+	  1' thingy if su returns 'Authentication failure'
+
+	* src/su.c:
+	- use >& to redirect instead of 2>&1 to make
+	  non-bash shells happy (Closes: #203386,
+	  #203387)
+
+2003-07-24  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.13
+
+	* README:
+	- some explanations added
+
+	* src/gui.c, src/su.c:
+	- some modifications on the default label that's 
+	  presented explaining why it wants the password,
+	  and in the label behavior, in general
+
+	* src/gksu.c, src/xauth.c:
+	- added --ssh-fwd option, which uses just the :x.x
+	  part of display when working with xauth, for gksu
+	  to work on ssh X11 forwarding 
+	  (Closes Debian bug: #202532)
+
+2003-07-23  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.12
+
+2003-07-22  Gustavo Noronha Silva  <kov at debian.org>
+
+	* src/xauth.c:
+	- added output about xauth token, file, directory and
+	  display, for debuging purposes (when --debug is enabled)
+	- fixed clean_dir to remove the directory if it is empty
+	  before clean_dir is called
+
+	* src/su.c:
+	- do not show xauth's output, unless --debug is given
+	- get rid of bashism when calling xauth by using the
+	  env command
+
+	* src/gksu.c:
+	- added a --debug option, to ask for more verbose
+	  output
+
+2003-07-14  Gustavo Noronha Silva  <kov at debian.org>
+
+	* man/gksu.1:
+	- fixed --icon position
+
+2003-06-14  gettextize  <bug-gnu-gettext at gnu.org>
+
+	* Makefile.am (ACLOCAL_AMFLAGS): New variable.
+	* configure.ac (AC_CONFIG_FILES): Add m4/Makefile.
+	(AM_GNU_GETTEXT_VERSION): Bump to 0.12.1.
+
+2003-06-14  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.11
+
+	* Applied patch from Álvaro Peña <apg at esware.com>
+	  to HIG-ify gksu a bit more
+
+2003-05-24  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.10
+
+	* src/su.c:
+	- Why the hell do I want gksu to automaticaly go to
+	  background? Changed that, I guess that'll help
+	  lots of scripts.
+
+2003-05-10  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.9
+
+	* src/gksuexec.c:
+	- fixed the way the command is passed as argument
+	  to gksu to fix running programs with arguments (duh)
+
+2003-05-08  Gustavo Noronha Silva  <kov at debian.org>
+
+	* src/su.c:
+	- fixed bug which did not allow gksu to run programs
+	  with arguments like, say, 'emacs /etc/mozpluggerrc' =)
+
+2003-05-06  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac: added es.po to ALL_LINGUAS
+
+2003-05-02  Gustavo Noronha Silva  <kov at debian.org>
+
+	* configure.ac: added ru.po to ALL_LINGUAS
+
+2003-04-05  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.8
+
+	* src/xauth.c:
+	- initialize 'xauth' to avoid problems with junk
+	  thanks to Alex Stewart <am2stewa at uwaterloo.ca>
+
+	* src/gui.c:
+	- wait a bit longer before checking for the effectiveness of
+	  the keyboard/mouse grab
+
+2003-03-29  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.7
+
+	* src/gksu.c, src/xauth.c:
+	- remove references to sudo, at least for now
+
+	* src/sudo.{c,h}:
+	- removed, no longer provide sudo functionality, it
+	  doesn't work as well as it should
+
+2003-03-28  Gustavo Noronha Silva  <kov at debian.org>
+
+	* src/su.c:
+	- use xauth information to make the magic work
+
+	* src/xauth.c:
+	- implement prepare_xauth_su to handle Xauth in a safer way,
+	  by using the 'xauth' program instead of a world readable
+	  .Xauthorization file
+	- move the old way of doing things to the prepare_xauth_sudo
+	  function... sudo is a difficult piece of software to handle
+
+	* src/gksu.c:
+	- moved as much xauth specific stuff as I could to xauth.c
+
+2003-02-01  Allan Douglas  <allan_douglas at gmx.net>
+
+	* src/sudo.c:
+	- cleanups
+	
+2003-01-31  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.1
+
+	* AUTHORS:
+	- added Allan Douglas
+
+2003-01-31  Allan Douglas  <allan_douglas at gmx.net>
+
+	* src/su.c:
+	- fixed the "missing output" bug
+
+2003-01-30  Allan Douglas  <allan_douglas at gmx.net>
+
+	* configure.ac:
+	- removed yacc dependency
+
+	* src/su.c:
+	- cleanups
+
+2003-01-30 Gustavo Noronha Silva   <kov at debian.org>
+
+	* src/su.c, src/sudo.c: 
+	- fixed some stuff pointed by my friend "o_0" =P
+
+	* src/gksuexec.c:
+	- has an 'advanced' dialog to select options
+	'login_shell' and '--preserv-env' for gksu
+
+2003-01-30  Gustavo Noronha Silva  <kov at debian.org>
+
+	* src/gksuexec.c:
+	- has an 'advanced' dialog to select options
+	  'login_shell' and '--preserv-env' for gksu
+
+2003-01-29  Gustavo Noronha Silva  <kov at debian.org>
+
+	* man/gksu.1:
+	- added reference for gksuexec command
+	- updated with the help of the 'help2man' command
+
+	* man/gksuexec.1: (new)
+	- wrote manpage to the new command
+
+	* man/Makefile.am: (new)
+	- install manpages
+
+	* src/gksu.c:
+	- fixed small and harmless segfault when free'ing
+	  conf.title
+	- accept -i, --icon to set window's icon
+	- print-pass' message no longer assumes root user
+
+	* src/gui.c:
+	- use gksu's icon at the window, instead of the
+	  question mark
+	- use conf.icon to set gksu window's icon
+
+2003-01-29  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.9.0
+
+	* src/gksuexec.c:
+	- a new program, a dialog to ask for other informations
+	  as a wrapper to gksu's command line
+
+	* src/util.{c,h}, src/gui.{c,h}:
+	- moved gk_dialog from gui to util to make it easier
+	  for gksuexec to use it
+
+	* gksuexec.desktop:
+	- new icon for GNOME, to run gksuexec
+
+2003-01-28  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.8.5
+
+	* src/su.c:
+	- does not ask for password when the real uid
+	  is 0 (see http://bugs.debian.org/178675)
+
+	* src/gksu.c:
+	- minor aesthetical fixes
+
+2003-01-22  Gustavo Noronha Silva  <kov at debian.org>
+
+	* Release 0.8.4
+
+2003-01-14  Gustavo Noronha Silva  <kov at debian.org>
+
+	* src/Makefile.am:
+	- define DATA_DIR
+	- add optimization on compilation
+
+	* src/gui.c:
+	- set default windows icon (requires Gtk+2.2)
+
+	* gksu.png:
+	- new icon, from art.gnome.org, Authorization.png
+
+	* gksu.png -> gksu-terminal.png:
+	- renamed icon for gnome's desktop icon
+
+2003-01-14  Gustavo Noronha Silva  <kov at debian.org>
+
+	* 0.8.3 Release
+
+	* clean up to the build system, using autoconf
+	  2.50 and automake-1.6
+
+	* man/gksu.1:
+	- fixed WHATIS entry
+
+	* gksu.desktop, gksu.png:
+	- icon for GNOME's System menu, to open a terminal
+	  as the root user
+
+2003-01-14  Gustavo Noronha Silva  <kov at debian.org>
+
+	* 0.8.2 Release
+	- changed configure.in
+
+	* src/gksu.c:
+	- make reset environment the default, changed:
+	  reset-env, r to preserv-env, k
+	- make not login shell the default, again, it
+	  will make the Xauth stuff break... duh
+
+	* src/su.c, src/sudo.c:
+	- yes, yes, auto-background again =P
+
+	* src/gui.c:
+	- cleans the Xauth directory in case the dialog is
+	  canceled or closed
+	- changed buttons' positions to reflect the changes
+	  that happened to GNOME2
+
+	* src/gksu.c:
+	- made title more i18n friendly, fixed some small
+	  memory leaks
+
+	* po/pt_BR.po:
+	- updated translation
+
+2003-01-12  Gustavo Noronha Silva  <kov at debian.org>
+
+	* src/gksu.c:
+	- make login shell by default
+
+	* src/su.c, src/sudo.c:
+	- no grandchild, no auto-background anymore
+	- fixes on outputing things
+
+2002-08-13  gettextize  <bug-gnu-gettext at gnu.org>
+
+	* Makefile.am (SUBDIRS): Add m4.
+	(SUBDIRS): Remove intl.
+	(ACLOCAL_AMFLAGS): New variable.
+	(EXTRA_DIST): New variable.
+
+	* configure.in (AC_OUTPUT): Add m4/Makefile.
+
+2002-02-18  Gustavo Noronha Silva  <kov at debian.org>
+
+	* gksu: initial version.
+

Deleted: libgksu/tags/2.0.9/libgksu/gksu-run-helper.c
===================================================================
--- libgksu/trunk/libgksu/gksu-run-helper.c	2009-02-23 02:20:27 UTC (rev 840)
+++ libgksu/tags/2.0.9/libgksu/gksu-run-helper.c	2009-03-04 18:55:14 UTC (rev 848)
@@ -1,184 +0,0 @@
-/*
- * Gksu -- a library providing access to su functionality
- * Copyright (C) 2004 Gustavo Noronha Silva
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#include <glib.h>
-
-#include "defines.h"
-
-#include "../config.h"
-
-void strip (gchar *string)
-{
-  if (string[strlen(string) - 1] == '\n')
-    string[strlen(string) - 1] = '\0';
-}
-
-/**
- * clean_dir:
- * @dirname: the temporary directory created by gksu for xauth
- *
- * Removes the temporary directory created to hold the X authorization
- * file, and of course, the file itself.
- */
-void
-clean_dir (const gchar *dirname)
-{
-  gchar *xauthname;
-  
-  xauthname = g_strdup_printf ("%s/.Xauthority", dirname);
-  unlink (xauthname);
-  g_free (xauthname);
-
-  xauthname = g_strdup_printf ("%s/.Xauthority.tmp", dirname);
-  unlink (xauthname);
-  g_free (xauthname);
-
-  if (rmdir (dirname))
-    fprintf (stderr, "ERROR: unable to remove directory %s: %s",
-	     dirname, strerror (errno));
-}
-
-void read_gstring_from_stdin(GString *s)
-{
-  gchar buffer[255];
-  char *readp;
-  do
-  {
-     readp = fgets(buffer, sizeof(buffer), stdin);
-     if(readp == NULL)
-	return;
-     strip (buffer);
-     g_string_append(s, buffer);
-  } while (sizeof(buffer)-1 == strlen(readp));
-  return;
-}
-
-int
-main (int argc, char **argv)
-{
-  gchar *command = NULL;
-
-  gchar *xauth_dirtemplate = g_strdup ("/tmp/" PACKAGE_NAME "-XXXXXX");
-
-  gchar *xauth_bin = NULL;
-
-  gchar *xauth_dir = NULL;
-  gchar *xauth_file = NULL;
-
-  gchar *xauth_display = NULL;
-  gchar *xauth_token = NULL;
-  gchar *sn_id = NULL;
-
-  gint return_code;
-
-  if (argc < 2)
-    {
-      fprintf (stderr, "gksu: command missing");
-      return 1;
-    }
-
-  xauth_dir = mkdtemp (xauth_dirtemplate);
-  if (!xauth_dir)
-    {
-      fprintf (stderr, "gksu: failed creating xauth_dir\n");
-      return 1;
-    }
-
-  fprintf (stderr, "gksu: waiting\n");
-
-  xauth_file = g_strdup_printf ("%s/.Xauthority",
-				xauth_dir);
-
-  GString *s = g_string_sized_new(255);
-  read_gstring_from_stdin(s);
-
-  /* strlen ("gksu-run: ") == 10, see su.c */
-  xauth_display = g_strdup_printf ("%s", s->str + 10);
-
-  s = g_string_truncate(s,0);
-  read_gstring_from_stdin(s);
-
-  sn_id = g_strdup_printf ("%s", s->str + 10);
-  setenv("DESKTOP_STARTUP_ID", sn_id, TRUE);
-
-  s = g_string_truncate(s,0);
-  read_gstring_from_stdin(s);
-
-  xauth_token = g_strdup_printf ("%s", s->str + 10);
-
-  /* a bit more security is always fine */
-  {
-    FILE *file;
-    gchar *tmpfilename = g_strdup_printf ("%s.tmp",
-					  xauth_file);
-
-    file = fopen (tmpfilename, "w");
-    if (!file)
-      {
-	fprintf (stderr, "gksu: error writing temporary auth file\n");
-	return 1;
-      }
-    fwrite (xauth_token, sizeof (gchar), strlen (xauth_token), file);
-    fclose (file);
-    chmod (tmpfilename, S_IRUSR|S_IWUSR);
-    
-    setenv ("XAUTHORITY", xauth_file, TRUE);
-
-    /* find out where the xauth binary is located */
-    if (g_file_test ("/usr/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
-      xauth_bin = "/usr/bin/xauth";
-    else if (g_file_test ("/usr/X11R6/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
-      xauth_bin = "/usr/X11R6/bin/xauth";
-    else
-      {
-	fprintf (stderr,
-		 _("Failed to obtain xauth key: xauth binary not found "
-		   "at usual locations"));
-
-	return 1;
-      }
-    command =
-      g_strdup_printf ("%s add %s . \"`cat %s.tmp`\""
-		       " > /dev/null 2>&1", xauth_bin,
-		       xauth_display, xauth_file);
-
-    system (command);
-
-    return_code = system (argv[1]);
-    
-    clean_dir (xauth_dir);
-    g_string_free(s, TRUE);
-    if (WIFEXITED(return_code))
-    {
-      return WEXITSTATUS(return_code);
-    } else if (WIFSIGNALED(return_code)) {
-      return -1;
-    }
-  }
-}

Copied: libgksu/tags/2.0.9/libgksu/gksu-run-helper.c (from rev 845, libgksu/trunk/libgksu/gksu-run-helper.c)
===================================================================
--- libgksu/tags/2.0.9/libgksu/gksu-run-helper.c	                        (rev 0)
+++ libgksu/tags/2.0.9/libgksu/gksu-run-helper.c	2009-03-04 18:55:14 UTC (rev 848)
@@ -0,0 +1,190 @@
+/*
+ * Gksu -- a library providing access to su functionality
+ * Copyright (C) 2004 Gustavo Noronha Silva
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <glib.h>
+
+#include "defines.h"
+
+#include "../config.h"
+
+void strip (gchar *string)
+{
+  if (string[strlen(string) - 1] == '\n')
+    string[strlen(string) - 1] = '\0';
+}
+
+/**
+ * clean_dir:
+ * @dirname: the temporary directory created by gksu for xauth
+ *
+ * Removes the temporary directory created to hold the X authorization
+ * file, and of course, the file itself.
+ */
+void
+clean_dir (const gchar *dirname)
+{
+  gchar *xauthname;
+  
+  xauthname = g_strdup_printf ("%s/.Xauthority", dirname);
+  unlink (xauthname);
+  g_free (xauthname);
+
+  xauthname = g_strdup_printf ("%s/.Xauthority.tmp", dirname);
+  unlink (xauthname);
+  g_free (xauthname);
+
+  if (rmdir (dirname))
+    fprintf (stderr, "ERROR: unable to remove directory %s: %s",
+	     dirname, strerror (errno));
+}
+
+void read_gstring_from_stdin(GString *s)
+{
+  gchar buffer[255];
+  char *readp;
+  do
+  {
+     readp = fgets(buffer, sizeof(buffer), stdin);
+     if(readp == NULL)
+	return;
+     strip (buffer);
+     g_string_append(s, buffer);
+  } while (sizeof(buffer)-1 == strlen(readp));
+  return;
+}
+
+int
+main (int argc, char **argv)
+{
+  gchar *command = NULL;
+
+  gchar *xauth_dirtemplate = g_strdup ("/tmp/" PACKAGE_NAME "-XXXXXX");
+
+  gchar *xauth_bin = NULL;
+
+  gchar *xauth_dir = NULL;
+  gchar *xauth_file = NULL;
+
+  gchar *xauth_display = NULL;
+  gchar *xauth_token = NULL;
+  gchar *sn_id = NULL;
+
+  gint return_code;
+
+  if (argc < 2)
+    {
+      fprintf (stderr, "gksu: command missing");
+      return 1;
+    }
+
+  xauth_dir = mkdtemp (xauth_dirtemplate);
+  if (!xauth_dir)
+    {
+      fprintf (stderr, "gksu: failed creating xauth_dir\n");
+      return 1;
+    }
+
+  fprintf (stderr, "gksu: waiting\n");
+
+  xauth_file = g_strdup_printf ("%s/.Xauthority",
+				xauth_dir);
+
+  GString *s = g_string_sized_new(255);
+  read_gstring_from_stdin(s);
+
+  /* strlen ("gksu-run: ") == 10, see su.c */
+  xauth_display = g_strdup_printf ("%s", s->str + 10);
+
+  s = g_string_truncate(s,0);
+  read_gstring_from_stdin(s);
+
+  sn_id = g_strdup_printf ("%s", s->str + 10);
+  setenv("DESKTOP_STARTUP_ID", sn_id, TRUE);
+
+  /* cleanup the environment; some variables we bring from the user
+   * environment make gconf-based applications misbehaving these days
+   */
+  unsetenv ("ORBIT_SOCKETDIR");
+  unsetenv ("DBUS_SESSION_BUS_ADDRESS");
+
+  s = g_string_truncate(s,0);
+  read_gstring_from_stdin(s);
+
+  xauth_token = g_strdup_printf ("%s", s->str + 10);
+
+  /* a bit more security is always fine */
+  {
+    FILE *file;
+    gchar *tmpfilename = g_strdup_printf ("%s.tmp",
+					  xauth_file);
+
+    file = fopen (tmpfilename, "w");
+    if (!file)
+      {
+	fprintf (stderr, "gksu: error writing temporary auth file\n");
+	return 1;
+      }
+    fwrite (xauth_token, sizeof (gchar), strlen (xauth_token), file);
+    fclose (file);
+    chmod (tmpfilename, S_IRUSR|S_IWUSR);
+    
+    setenv ("XAUTHORITY", xauth_file, TRUE);
+
+    /* find out where the xauth binary is located */
+    if (g_file_test ("/usr/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
+      xauth_bin = "/usr/bin/xauth";
+    else if (g_file_test ("/usr/X11R6/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
+      xauth_bin = "/usr/X11R6/bin/xauth";
+    else
+      {
+	fprintf (stderr,
+		 _("Failed to obtain xauth key: xauth binary not found "
+		   "at usual locations"));
+
+	return 1;
+      }
+    command =
+      g_strdup_printf ("%s add %s . \"`cat %s.tmp`\""
+		       " > /dev/null 2>&1", xauth_bin,
+		       xauth_display, xauth_file);
+
+    system (command);
+
+    return_code = system (argv[1]);
+    
+    clean_dir (xauth_dir);
+    g_string_free(s, TRUE);
+    if (WIFEXITED(return_code))
+    {
+      return WEXITSTATUS(return_code);
+    } else if (WIFSIGNALED(return_code)) {
+      return -1;
+    }
+  }
+}

Deleted: libgksu/tags/2.0.9/libgksu/libgksu.c
===================================================================
--- libgksu/trunk/libgksu/libgksu.c	2009-02-23 02:20:27 UTC (rev 840)
+++ libgksu/tags/2.0.9/libgksu/libgksu.c	2009-03-04 18:55:14 UTC (rev 848)
@@ -1,3087 +0,0 @@
-/*
- * Gksu -- a library providing access to su functionality
- * Copyright (C) 2004 Gustavo Noronha Silva
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <pty.h>
-#include <pwd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/select.h>
-#include <errno.h>
-
-#include <glibtop.h>
-#include <glibtop/procstate.h>
-
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-
-#define SN_API_NOT_YET_FROZEN
-#include <libsn/sn.h>
-
-#include <gtk/gtk.h>
-#include <locale.h>
-
-#include <gconf/gconf-client.h>
-#include <gnome-keyring.h>
-
-#include "defines.h"
-#include "../config.h"
-
-#include "libgksu.h"
-#include "../libgksuui/gksuui-dialog.h"
-
-static void
-gksu_context_launch_complete (GksuContext *context);
-
-GType
-gksu_error_get_type (void)
-{
-  static GType etype = 0;
-  if (etype == 0) {
-    static const GEnumValue values[] = {
-      { GKSU_ERROR_HELPER, "GKSU_ERROR_HELPER", "helper" },
-      { GKSU_ERROR_NOCOMMAND, "GKSU_ERROR_NOCOMMAND", "nocommand" },
-      { GKSU_ERROR_NOPASSWORD, "GKSU_ERROR_NOPASSWORD", "nopassword" },
-      { GKSU_ERROR_FORK, "GKSU_ERROR_FORK", "fork" },
-      { GKSU_ERROR_EXEC, "GKSU_ERROR_EXEC", "exec" },
-      { GKSU_ERROR_PIPE, "GKSU_ERROR_PIPE", "pipe" },
-      { GKSU_ERROR_PIPEREAD, "GKSU_ERROR_PIPEREAD", "piperead" },
-      { GKSU_ERROR_WRONGPASS, "GKSU_ERROR_WRONGPASS", "wrongpass" },
-      { GKSU_ERROR_CHILDFAILED, "GKSU_ERROR_CHILDFAILED", "childfailed" },
-      { GKSU_ERROR_CANCELED, "GKSU_ERROR_CANCELED", "canceled" },
-      { GKSU_ERROR_WRONGAUTOPASS, "GKSU_ERROR_WRONGAUTOPASS", "wrongautopass" },
-      { 0, NULL, NULL }
-    };
-    etype = g_enum_register_static ("GksuError", values);
-  }
-  return etype;
-}
-
-static pid_t
-test_lock(const char* fname)
-{
-   int FD = open(fname, 0);
-   if(FD < 0) {
-      if(errno == ENOENT) {
-	 // File does not exist
-	 return 0;
-      } else {
-	 perror("open");
-	 return(-1);
-      }
-   }
-   struct flock fl;
-   fl.l_type = F_WRLCK;
-   fl.l_whence = SEEK_SET;
-   fl.l_start = 0;
-   fl.l_len = 0;
-   if (fcntl(FD, F_GETLK, &fl) < 0) {
-      g_critical("fcntl error");
-      close(FD);
-      return(-1);
-   }
-   close(FD);
-   // lock is available
-   if(fl.l_type == F_UNLCK)
-      return(0);
-   // file is locked by another process
-   return (fl.l_pid);
-}
-
-static int
-get_lock(const char *File)
-{
-   int FD = open(File,O_RDWR | O_CREAT | O_TRUNC,0640);
-   if (FD < 0)
-   {
-      // Read only .. cant have locking problems there.
-      if (errno == EROFS)
-      {
-	 g_warning(_("Not using locking for read only lock file %s"),File);
-	 return dup(0);       // Need something for the caller to close
-      }
-
-      // Feh.. We do this to distinguish the lock vs open case..
-      errno = EPERM;
-      return -1;
-   }
-   fcntl(FD,F_SETFD, FD_CLOEXEC);
-
-   // Aquire a write lock
-   struct flock fl;
-   fl.l_type = F_WRLCK;
-   fl.l_whence = SEEK_SET;
-   fl.l_start = 0;
-   fl.l_len = 0;
-   if (fcntl(FD,F_SETLK,&fl) == -1)
-   {
-      if (errno == ENOLCK)
-      {
-	 g_warning(_("Not using locking for nfs mounted lock file %s"), File);
-	 unlink(File);
-	 close(FD);
-	 return dup(0);       // Need something for the caller to close
-      }
-
-      int Tmp = errno;
-      close(FD);
-      errno = Tmp;
-      return -1;
-   }
-
-   return FD;
-}
-
-/*
- * code 'stolen' from gnome-session's logout.c
- *
- * Written by Owen Taylor <otaylor at redhat.com>
- * Copyright (C) Red Hat
- */
-typedef struct {
-  GdkScreen    *screen;
-  int           monitor;
-  GdkRectangle  area;
-  int           rowstride;
-  GdkWindow    *root_window;
-  GdkWindow    *draw_window;
-  GdkPixbuf    *start_pb, *end_pb, *frame;
-  guchar       *start_p, *end_p, *frame_p;
-  GTimeVal      start_time;
-  GdkGC        *gc;
-} FadeoutData;
-
-FadeoutData *fade_data = NULL;
-static GList *fadeout_windows = NULL;
-
-#define FADE_DURATION 500.0
-
-int
-gsm_screen_get_width (GdkScreen *screen,
-		      int        monitor)
-{
-	GdkRectangle geometry;
-
-	gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
-
-	return geometry.width;
-}
-
-int
-gsm_screen_get_height (GdkScreen *screen,
-		       int        monitor)
-{
-	GdkRectangle geometry;
-
-	gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
-
-	return geometry.height;
-}
-
-int
-gsm_screen_get_x (GdkScreen *screen,
-		  int        monitor)
-{
-	GdkRectangle geometry;
-
-	gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
-
-	return geometry.x;
-}
-
-int
-gsm_screen_get_y (GdkScreen *screen,
-		  int        monitor)
-{
-	GdkRectangle geometry;
-
-	gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
-
-	return geometry.y;
-}
-
-static void
-get_current_frame (FadeoutData *fadeout,
-		   double    sat)
-{
-  guchar *sp, *ep, *fp;
-  int i, j, width, offset;
-
-  width = fadeout->area.width * 3;
-  offset = 0;
-
-  for (i = 0; i < fadeout->area.height; i++)
-    {
-      sp = fadeout->start_p + offset;
-      ep = fadeout->end_p   + offset;
-      fp = fadeout->frame_p + offset;
-
-      for (j = 0; j < width; j += 3)
-	{
-	  guchar r = abs (*(sp++) - ep[0]);
-	  guchar g = abs (*(sp++) - ep[1]);
-	  guchar b = abs (*(sp++) - ep[2]);
-
-	  *(fp++) = *(ep++) + r * sat;
-	  *(fp++) = *(ep++) + g * sat;
-	  *(fp++) = *(ep++) + b * sat;
-	}
-
-      offset += fadeout->rowstride;
-    }
-}
-
-static void
-darken_pixbuf (GdkPixbuf *pb)
-{
-  int width, height, rowstride;
-  int i, j;
-  guchar *p, *pixels;
-
-  width     = gdk_pixbuf_get_width (pb) * 3;
-  height    = gdk_pixbuf_get_height (pb);
-  rowstride = gdk_pixbuf_get_rowstride (pb);
-  pixels    = gdk_pixbuf_get_pixels (pb);
-
-  for (i = 0; i < height; i++)
-    {
-      p = pixels + (i * rowstride);
-      for (j = 0; j < width; j++)
-	p [j] >>= 1;
-    }
-}
-
-static gboolean
-fadeout_callback (FadeoutData *fadeout)
-{
-  GTimeVal current_time;
-  double elapsed, percent;
-
-  g_get_current_time (&current_time);
-  elapsed = ((((double)current_time.tv_sec - fadeout->start_time.tv_sec) * G_USEC_PER_SEC +
-	      (current_time.tv_usec - fadeout->start_time.tv_usec))) / 1000.0;
-
-  if (elapsed < 0)
-    {
-      g_warning ("System clock seemed to go backwards?");
-      elapsed = G_MAXDOUBLE;
-    }
-
-  if (elapsed > FADE_DURATION)
-    {
-      gdk_draw_pixbuf (fadeout->draw_window,
-		       fadeout->gc,
-		       fadeout->end_pb,
-		       0, 0,
-		       0, 0,
-		       fadeout->area.width,
-		       fadeout->area.height,
-		       GDK_RGB_DITHER_NONE,
-		       0, 0);
-
-      return FALSE;
-    }
-
-  percent = elapsed / FADE_DURATION;
-
-  get_current_frame (fadeout, 1.0 - percent);
-  gdk_draw_pixbuf (fadeout->draw_window,
-		   fadeout->gc,
-		   fadeout->frame,
-		   0, 0,
-		   0, 0,
-		   fadeout->area.width,
-		   fadeout->area.height,
-		   GDK_RGB_DITHER_NONE,
-		   0, 0);
-
-  gdk_flush ();
-
-  return TRUE;
-}
-
-static void
-hide_fadeout_windows (void)
-{
-  GList *l;
-
-  for (l = fadeout_windows; l; l = l->next)
-    {
-      gdk_window_hide (GDK_WINDOW (l->data));
-      g_object_unref (l->data);
-    }
-
-  g_list_free (fadeout_windows);
-  fadeout_windows = NULL;
-}
-
-static gboolean
-fadein_callback (FadeoutData *fadeout)
-{
-  GTimeVal current_time;
-  double elapsed, percent;
-
-  g_get_current_time (&current_time);
-  elapsed = ((((double)current_time.tv_sec - fadeout->start_time.tv_sec) * G_USEC_PER_SEC +
-	      (current_time.tv_usec - fadeout->start_time.tv_usec))) / 1000.0;
-
-  if (elapsed < 0)
-    {
-      g_warning ("System clock seemed to go backwards?");
-      elapsed = G_MAXDOUBLE;
-    }
-
-  if (elapsed > FADE_DURATION)
-    {
-      gdk_draw_pixbuf (fadeout->draw_window,
-		       fadeout->gc,
-		       fadeout->end_pb,
-		       0, 0,
-		       0, 0,
-		       fadeout->area.width,
-		       fadeout->area.height,
-		       GDK_RGB_DITHER_NONE,
-		       0, 0);
-
-      g_object_unref (fadeout->gc);
-      g_object_unref (fadeout->start_pb);
-      g_object_unref (fadeout->end_pb);
-      g_object_unref (fadeout->frame);
-
-      g_free (fadeout);
-
-      hide_fadeout_windows ();
-
-      return FALSE;
-    }
-
-  percent = elapsed / FADE_DURATION;
-
-  get_current_frame (fadeout, percent);
-  gdk_draw_pixbuf (fadeout->draw_window,
-		   fadeout->gc,
-		   fadeout->frame,
-		   0, 0,
-		   0, 0,
-		   fadeout->area.width,
-		   fadeout->area.height,
-		   GDK_RGB_DITHER_NONE,
-		   0, 0);
-
-  gdk_flush ();
-
-  return TRUE;
-}
-
-static void
-fadeout_screen (GdkScreen *screen,
-		int        monitor)
-{
-  GdkWindowAttr attr;
-  int attr_mask;
-  GdkGCValues values;
-  FadeoutData *fadeout;
-
-  fadeout = g_new (FadeoutData, 1);
-
-  fadeout->screen = screen;
-  fadeout->monitor = monitor;
-
-  fadeout->area.x = gsm_screen_get_x (screen, monitor);
-  fadeout->area.y = gsm_screen_get_y (screen, monitor);
-  fadeout->area.width = gsm_screen_get_width (screen, monitor);
-  fadeout->area.height = gsm_screen_get_height (screen, monitor);
-
-  fadeout->root_window = gdk_screen_get_root_window (screen);
-  attr.window_type = GDK_WINDOW_CHILD;
-  attr.x = fadeout->area.x;
-  attr.y = fadeout->area.y;
-  attr.width = fadeout->area.width;
-  attr.height = fadeout->area.height;
-  attr.wclass = GDK_INPUT_OUTPUT;
-  attr.visual = gdk_screen_get_system_visual (fadeout->screen);
-  attr.colormap = gdk_screen_get_default_colormap (fadeout->screen);
-  attr.override_redirect = TRUE;
-  attr_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_NOREDIR;
-
-  fadeout->draw_window = gdk_window_new (fadeout->root_window, &attr, attr_mask);
-  fadeout_windows = g_list_prepend (fadeout_windows, fadeout->draw_window);
-
-  fadeout->start_pb = gdk_pixbuf_get_from_drawable (NULL,
-						    fadeout->root_window,
-						    NULL,
-						    fadeout->area.x,
-						    fadeout->area.y,
-						    0, 0,
-						    fadeout->area.width,
-						    fadeout->area.height);
-
-  fadeout->end_pb = gdk_pixbuf_copy (fadeout->start_pb);
-  darken_pixbuf (fadeout->end_pb);
-
-  fadeout->frame = gdk_pixbuf_copy (fadeout->start_pb);
-  fadeout->rowstride = gdk_pixbuf_get_rowstride (fadeout->start_pb);
-
-  fadeout->start_p = gdk_pixbuf_get_pixels (fadeout->start_pb);
-  fadeout->end_p   = gdk_pixbuf_get_pixels (fadeout->end_pb);
-  fadeout->frame_p = gdk_pixbuf_get_pixels (fadeout->frame);
-
-  values.subwindow_mode = GDK_INCLUDE_INFERIORS;
-
-  fadeout->gc = gdk_gc_new_with_values (fadeout->root_window, &values, GDK_GC_SUBWINDOW);
-
-  gdk_window_set_back_pixmap (fadeout->draw_window, NULL, FALSE);
-  gdk_window_show (fadeout->draw_window);
-  gdk_draw_pixbuf (fadeout->draw_window,
-		   fadeout->gc,
-		   fadeout->frame,
-		   0, 0,
-		   0, 0,
-		   fadeout->area.width,
-		   fadeout->area.height,
-		   GDK_RGB_DITHER_NONE,
-		   0, 0);
-
-  g_get_current_time (&fadeout->start_time);
-  g_idle_add ((GSourceFunc) fadeout_callback, fadeout);
-
-  fade_data = fadeout;
-}
-
-/* End of 'stolen' code */
-
-#define GRAB_TRIES	16
-#define GRAB_WAIT	250 /* milliseconds */
-
-typedef enum
-  {
-    FAILED_GRAB_MOUSE,
-    FAILED_GRAB_KEYBOARD
-  } FailedGrabWhat;
-
-void
-report_failed_grab (FailedGrabWhat what)
-{
-  GtkWidget *dialog;
-
-  dialog = g_object_new (GTK_TYPE_MESSAGE_DIALOG,
-			 "message-type", GTK_MESSAGE_WARNING,
-			 "buttons", GTK_BUTTONS_CLOSE,
-			 NULL);
-
-  switch (what)
-    {
-    case FAILED_GRAB_MOUSE:
-      gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG(dialog),
-				     _("<b><big>Could not grab your mouse.</big></b>"
-				       "\n\n"
-				       "A malicious client may be eavesdropping "
-				       "on your session or you may have just clicked "
-				       "a menu or some application just decided to get "
-				       "focus."
-				       "\n\n"
-				       "Try again."));
-
-      break;
-    case FAILED_GRAB_KEYBOARD:
-      gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG(dialog),
-				     _("<b><big>Could not grab your keyboard.</big></b>"
-				       "\n\n"
-				       "A malicious client may be eavesdropping "
-				       "on your session or you may have just clicked "
-				       "a menu or some application just decided to get "
-				       "focus."
-				       "\n\n"
-				       "Try again."));
-      break;
-    }
-
-  gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
-  gtk_dialog_run (GTK_DIALOG(dialog));
-  gtk_widget_destroy (dialog);
-
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-}
-
-int
-grab_keyboard_and_mouse (GtkWidget *dialog)
-{
-  GdkGrabStatus status;
-  gint grab_tries = 0;
-  gint lock = -1;
-  pid_t pid;
-
-  gchar *fname = g_strdup (getenv ("GKSU_LOCK_FILE"));
-  if (fname == NULL)
-    fname = g_strdup_printf ("%s/.gksu.lock", getenv ("HOME"));
-
-  pid = test_lock (fname);
-
-  if (pid != 0)
-    {
-      g_warning ("Lock taken by pid: %i. Exiting.", pid);
-      exit (0);
-    }
-
-  lock = get_lock(fname);
-  if( lock < 0)
-    g_warning ("Unable to create lock file.");
-  g_free (fname);
-
-  gdk_threads_enter ();
-  fadeout_screen (gdk_screen_get_default (), 0);
-  gtk_widget_show_all (dialog);
-
-  /* reset cursor */
-  gdk_window_set_cursor(dialog->window, gdk_cursor_new(GDK_LEFT_PTR));
-
-  for(;;)
-    {
-      status = gdk_pointer_grab ((GTK_WIDGET(dialog))->window, TRUE, 0, NULL,
-				 NULL, GDK_CURRENT_TIME);
-      if (status == GDK_GRAB_SUCCESS)
-	break;
-      usleep (GRAB_WAIT * 1000);
-      if (++grab_tries > GRAB_TRIES)
-	{
-	  gtk_widget_hide (dialog);
-	  g_get_current_time (&fade_data->start_time);
-	  while (fadein_callback (fade_data) != FALSE);
-	  report_failed_grab (FAILED_GRAB_MOUSE);
-	  exit (1);
-	  break;
-	}
-    }
-
-  for(;;)
-    {
-      status = gdk_keyboard_grab ((GTK_WIDGET(dialog))->window,
-				  FALSE, GDK_CURRENT_TIME);
-      if (status == GDK_GRAB_SUCCESS)
-	break;
-
-      usleep(GRAB_WAIT * 1000);
-
-      if (++grab_tries > GRAB_TRIES)
-	{
-	  gtk_widget_hide (dialog);
-	  g_get_current_time (&fade_data->start_time);
-	  while (fadein_callback (fade_data) != FALSE);
-	  report_failed_grab (FAILED_GRAB_KEYBOARD);
-	  exit (1);
-	  break;
-	}
-    }
-
-  /* we "raise" the window because there is a race here for
-   * focus-follow-mouse and auto-raise WMs that may put the window
-   * in the background and confuse users
-   */
-  gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
-
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-  return lock;
-}
-
-void
-ungrab_keyboard_and_mouse (int lock)
-{
-  /* Ungrab */
-  gdk_pointer_ungrab(GDK_CURRENT_TIME);
-  gdk_keyboard_ungrab(GDK_CURRENT_TIME);
-  gdk_flush();
-
-  g_get_current_time (&fade_data->start_time);
-  while (fadein_callback (fade_data) != FALSE);
-  gdk_threads_leave();
-
-  close(lock);
-}
-
-static gchar*
-get_gnome_keyring_password (GksuContext *context)
-{
-  GnomeKeyringAttributeList *attributes;
-  GnomeKeyringAttribute attribute;
-  GnomeKeyringResult result;
-  GList *list;
-
-  attributes = gnome_keyring_attribute_list_new ();
-
-  attribute.name = g_strdup ("user");
-  attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
-  attribute.value.string = g_strdup (gksu_context_get_user (context));
-  g_array_append_val (attributes, attribute);
-
-  attribute.name = g_strdup ("type");
-  attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
-  attribute.value.string = g_strdup ("local");
-  g_array_append_val (attributes, attribute);
-
-  attribute.name = g_strdup ("creator");
-  attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
-  attribute.value.string = g_strdup ("gksu");
-  g_array_append_val (attributes, attribute);
-
-  list = g_list_alloc();
-
-  result = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
-					  attributes,
-					  &list);
-  gnome_keyring_attribute_list_free (attributes);
-  if (
-      (result == GNOME_KEYRING_RESULT_OK) &&
-      (g_list_length(list) >= 1)
-      )
-    {
-      GnomeKeyringFound *found = list->data;
-      gint password_length = strlen (found->secret);
-      gchar *password;
-
-      password = g_locale_from_utf8 (found->secret,
-				     password_length,
-				     NULL, NULL, NULL);
-      password_length = strlen (password);
-
-      if (password[password_length-1] == '\n')
-	password[password_length-1] = '\0';
-      return password;
-    }
-
-  return NULL;
-}
-
-static void
-keyring_create_item_cb (GnomeKeyringResult result,
-                        guint32 id, gpointer keyring_loop)
-{
-  g_main_loop_quit (keyring_loop);
-}
-
-static void
-set_gnome_keyring_password (GksuContext *context, gchar *password)
-{
-  GConfClient *gconf_client;
-  gboolean save_to_keyring;
-
-  gconf_client = context->gconf_client;
-  save_to_keyring = gconf_client_get_bool (gconf_client, BASE_PATH"save-to-keyring", NULL);
-
-  if (password && save_to_keyring)
-    {
-      static GMainLoop *keyring_loop = NULL;
-      GnomeKeyringAttributeList *attributes;
-      GnomeKeyringAttribute attribute;
-      GnomeKeyringResult result;
-
-      gchar *keyring_name;
-      gchar *key_name;
-
-      attributes = gnome_keyring_attribute_list_new ();
-
-      attribute.name = g_strdup ("user");
-      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
-      attribute.value.string = g_strdup (gksu_context_get_user (context));
-      g_array_append_val (attributes, attribute);
-
-      attribute.name = g_strdup ("type");
-      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
-      attribute.value.string = g_strdup ("local");
-      g_array_append_val (attributes, attribute);
-
-      attribute.name = g_strdup ("creator");
-      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
-      attribute.value.string = g_strdup ("gksu");
-      g_array_append_val (attributes, attribute);
-
-      key_name = g_strdup_printf ("Local password for user %s",
-				  gksu_context_get_user (context));
-
-      keyring_loop = g_main_loop_new (NULL, FALSE);
-
-      keyring_name = gconf_client_get_string (gconf_client, BASE_PATH"save-keyring", NULL);
-      if (keyring_name == NULL)
-	keyring_name = g_strdup ("session");
-
-      /* make sure the keyring exists; if an error occurs, use
-         the session keyring */
-      result = gnome_keyring_create_sync(keyring_name, NULL);
-      if ((result != GNOME_KEYRING_RESULT_OK) &&
-	  (result != GNOME_KEYRING_RESULT_ALREADY_EXISTS))
-	keyring_name = g_strdup ("session");
-
-      gnome_keyring_item_create (keyring_name,
-				 GNOME_KEYRING_ITEM_GENERIC_SECRET,
-				 key_name,
-				 attributes,
-				 password,
-				 TRUE,
-				 keyring_create_item_cb,
-				 keyring_loop, NULL);
-      gnome_keyring_attribute_list_free (attributes);
-      g_free (keyring_name);
-      g_main_loop_run (keyring_loop);
-    }
-}
-
-static void
-unset_gnome_keyring_password (GksuContext *context)
-{
-  GConfClient *gconf_client;
-  gboolean save_to_keyring;
-
-  GnomeKeyringAttributeList *attributes;
-  GnomeKeyringAttribute attribute;
-  GnomeKeyringResult result;
-  GList *list;
-
-  gconf_client = context->gconf_client;
-  save_to_keyring = gconf_client_get_bool (gconf_client, BASE_PATH"save-to-keyring", NULL);
-
-  if (save_to_keyring)
-    {
-      attributes = gnome_keyring_attribute_list_new ();
-
-      attribute.name = g_strdup ("user");
-      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
-      attribute.value.string = g_strdup (gksu_context_get_user (context));
-      g_array_append_val (attributes, attribute);
-
-      attribute.name = g_strdup ("type");
-      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
-      attribute.value.string = g_strdup ("local");
-      g_array_append_val (attributes, attribute);
-
-      attribute.name = g_strdup ("creator");
-      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
-      attribute.value.string = g_strdup ("gksu");
-      g_array_append_val (attributes, attribute);
-
-      list = g_list_alloc();
-
-      result = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
-					      attributes,
-					      &list);
-      gnome_keyring_attribute_list_free (attributes);
-      if (
-	  (result == GNOME_KEYRING_RESULT_OK) &&
-	  (g_list_length(list) == 1)
-	  )
-	{
-	  GnomeKeyringFound *found = list->data;
-
-	  gnome_keyring_item_delete_sync (found->keyring,
-					  found->item_id);
-	}
-    }
-}
-
-void
-get_configuration_options (GksuContext *context)
-{
-  GConfClient *gconf_client = context->gconf_client;
-  gboolean force_grab;
-
-  context->grab = !gconf_client_get_bool (gconf_client, BASE_PATH "disable-grab",
-					  NULL);
-  force_grab = gconf_client_get_bool (gconf_client, BASE_PATH "force-grab",
-				      NULL);
-  if (force_grab)
-    context->grab = TRUE;
-
-  context->sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
-					      NULL);
-}
-
-/**
- * su_ask_password:
- * @context: a #GksuContext
- * @prompt: the prompt that should be used instead of "Password: "
- * @data: data that is passed by gksu_*_full
- * @error: a pointer to pointer #GError that will be filled with
- * data if an error happens.
- *
- * This is a convenience function to create a #GksuuiDialog and
- * request the password.
- *
- * Returns: a newly allocated gchar containing the password
- * or NULL if an error happens or the user cancels the action
- */
-static gchar*
-su_ask_password (GksuContext *context, gchar *prompt,
-		 gpointer data, GError **error)
-{
-  GtkWidget *dialog = NULL;
-  gchar *msg;
-  gchar *password = NULL, *tmp = NULL;
-  int retvalue = 0;
-  int lock = 0;
-  GQuark gksu_quark;
-
-  gksu_quark = g_quark_from_string (PACKAGE);
-
-  if (context->grab)
-    dialog = g_object_new (GKSUUI_TYPE_DIALOG,
-			   "type", GTK_WINDOW_POPUP,
-			   "sudo-mode", context->sudo_mode,
-			   NULL);
-  else
-    dialog = gksuui_dialog_new (context->sudo_mode);
-
-  if (prompt)
-    gksuui_dialog_set_prompt (GKSUUI_DIALOG(dialog), _(prompt));
-
-  if (context->message)
-    gksuui_dialog_set_message (GKSUUI_DIALOG(dialog), context->message);
-  else
-    {
-      gchar *command = NULL;
-      if (context->description)
-	command = context->description;
-      else
-	command = context->command;
-
-      if (context->sudo_mode)
-	{
-	  if (!strcmp(context->user, "root"))
-	    msg = g_strdup_printf (_("<b><big>Enter your password to perform"
-				     " administrative tasks</big></b>\n\n"
-				     "The application '%s' lets you "
-				     "modify essential parts of your "
-				     "system."),
-				   command);
-	  else
-	    msg = g_strdup_printf (_("<b><big>Enter your password to run "
-				     "the application '%s' as user %s"
-				     "</big></b>"),
-				   command, context->user);
-	}
-      else
-	{
-        if (strcmp(gksu_context_get_user (context), "root") == 0)
-          msg = g_strdup_printf (_("<b><big>Enter the administrative password"
-                                   "</big></b>\n\n"
-                                   "The application '%s' lets you "
-                                   "modify essential parts of your "
-                                   "system."),
-				   command);
-        else
-          msg = g_strdup_printf (_("<b><big>Enter the password of %s to run "
-                                   "the application '%s'"
-                                   "</big></b>"),
-				   context->user, command);
-      }
-
-      gksuui_dialog_set_message (GKSUUI_DIALOG(dialog), msg);
-      g_free (msg);
-    }
-
-  if (context->alert)
-    gksuui_dialog_set_alert (GKSUUI_DIALOG(dialog), context->alert);
-
-  if (context->grab)
-    lock = grab_keyboard_and_mouse (dialog);
-  retvalue = gtk_dialog_run (GTK_DIALOG(dialog));
-  gtk_widget_hide (dialog);
-  if (context->grab)
-    ungrab_keyboard_and_mouse (lock);
-
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-  if (retvalue != GTK_RESPONSE_OK)
-    {
-      switch (retvalue)
-	{
-	case GTK_RESPONSE_CANCEL:
-	case GTK_RESPONSE_DELETE_EVENT:
-	  g_set_error (error, gksu_quark,
-		       GKSU_ERROR_CANCELED,
-		       _("Password prompt canceled."));
-	  if (context->sn_context)
-	    gksu_context_launch_complete (context);
-	}
-
-      gtk_widget_destroy (dialog);
-      while (gtk_events_pending ())
-	gtk_main_iteration ();
-
-      return NULL;
-    }
-
-  tmp = gksuui_dialog_get_password (GKSUUI_DIALOG(dialog));
-  password = g_locale_from_utf8 (tmp, strlen (tmp), NULL, NULL, NULL);
-  g_free (tmp);
-
-  gtk_widget_destroy (dialog);
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-
-  return password;
-}
-
-static void
-cb_toggled_cb (GtkWidget *button, gpointer data)
-{
-  GConfClient *gconf_client;
-  gchar *key;
-  gboolean toggled;
-  gchar *key_name;
-
-  g_return_if_fail (data != NULL);
-
-  key_name = (gchar*)data;
-
-  gconf_client = gconf_client_get_default ();
-  toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button));
-
-  key = g_strdup_printf (BASE_PATH "%s", key_name);
-
-  if (!strcmp (key_name, "display-no-pass-info"))
-    {
-      /* the meaning of the key is the exact opposite of the meaning
-	 of the answer - when the check button is checked the key must
-	 be off
-      */
-      gconf_client_set_bool (gconf_client, key, !toggled, NULL);
-    }
-  else
-    gconf_client_set_bool (gconf_client, key, toggled, NULL);
-
-  g_object_unref (gconf_client);
-
-  g_free (key);
-}
-
-void
-no_pass (GksuContext *context, gpointer data)
-{
-  GtkWidget *dialog;
-  GtkWidget *alignment;
-  GtkWidget *check_button;
-
-  gchar *command = NULL;
-
-  if (context->description)
-    command = context->description;
-  else
-    command = context->command;
-
-  dialog = gtk_message_dialog_new_with_markup (NULL, 0,
-					       GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
-					       _("<b><big>Granted permissions without asking "
-						 "for password</big></b>"
-						 "\n\n"
-						 "The '%s' program was started with "
-						 "the privileges of the %s user without "
-						 "the need to ask for a password, due to "
-						 "your system's authentication mechanism "
-						 "setup."
-						 "\n\n"
-						 "It is possible that you are being allowed "
-						 "to run specific programs as user %s "
-						 "without the need for a password, or that "
-						 "the password is cached."
-						 "\n\n"
-						 "This is not a problem report; it's "
-						 "simply a notification to make sure "
-						 "you are aware of this."),
-					       command,
-					       context->user,
-					       context->user);
-
-  alignment = gtk_alignment_new (0.5, 0.5, 0.6, 1);
-  gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), alignment, TRUE, TRUE, 2);
-
-  check_button = gtk_check_button_new_with_mnemonic (_("Do _not display this message again"));
-  g_signal_connect (G_OBJECT(check_button), "toggled",
-		    G_CALLBACK(cb_toggled_cb), "display-no-pass-info");
-  gtk_container_add (GTK_CONTAINER(alignment), check_button);
-
-  gtk_widget_show_all (dialog);
-  gtk_dialog_run (GTK_DIALOG(dialog));
-  gtk_widget_destroy (GTK_WIDGET(dialog));
-
-  while (gtk_events_pending ())
-    gtk_main_iteration ();
-}
-
-static void
-gksu_prompt_grab (GksuContext *context)
-{
-  GtkWidget *d;
-
-  d = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_QUESTION,
-					  GTK_BUTTONS_YES_NO,
-					  _("<b>Would you like your screen to be \"grabbed\"\n"
-					    "while you enter the password?</b>"
-					    "\n\n"
-					    "This means all applications will be paused to avoid\n"
-					    "the eavesdropping of your password by a a malicious\n"
-					    "application while you type it."));
-
-  if (gtk_dialog_run (GTK_DIALOG(d)) == GTK_RESPONSE_NO)
-    context->grab = FALSE;
-  else
-    context->grab = TRUE;
-
-  gtk_widget_destroy (d);
-}
-
-static void
-nullify_password (gchar *pass)
-{
-  if (pass)
-    {
-      memset(pass, 0, strlen(pass));
-      g_free (pass);
-    }
-  pass = NULL;
-}
-
-static gchar *
-get_process_name (pid_t pid)
-{
-  static gboolean init;
-  glibtop_proc_state buf;
-
-  if (!init) {
-    glibtop_init();
-    init = TRUE;
-  }
-
-  glibtop_get_proc_state (&buf, pid);
-  return strdup(buf.cmd);
-}
-
-static gchar *
-get_xauth_token (GksuContext *context, gchar *display)
-{
-  gchar *xauth_bin = NULL;
-  FILE *xauth_output;
-  gchar *tmp = NULL;
-  gchar *xauth = g_new0 (gchar, 256);
-
-  /* find out where the xauth binary is located */
-  if (g_file_test ("/usr/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
-    xauth_bin = "/usr/bin/xauth";
-  else if (g_file_test ("/usr/X11R6/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
-    xauth_bin = "/usr/X11R6/bin/xauth";
-  else
-    {
-      fprintf (stderr,
-	       "Failed to obtain xauth key: xauth binary not found "
-	       "at usual locations");
-
-      return NULL;
-    }
-
-  /* get the authorization token */
-  tmp = g_strdup_printf ("%s list %s | "
-			 "head -1 | awk '{ print $3 }'",
-			 xauth_bin,
-			 display);
-  if ((xauth_output = popen (tmp, "r")) == NULL)
-    {
-      fprintf (stderr,
-	       "Failed to obtain xauth key: %s",
-	       strerror(errno));
-      return NULL;
-    }
-  fread (xauth, sizeof(char), 255, xauth_output);
-  pclose (xauth_output);
-  g_free (tmp);
-
-  if (context->debug)
-    {
-      fprintf(stderr,
-	      "xauth: -%s-\n"
-	      "display: -%s-\n",
-	      xauth, display);
-    }
-
-  return xauth;
-}
-
-/**
- * prepare_xauth:
- *
- * Sets up the variables with values for the $DISPLAY
- * environment variable and xauth-related stuff. Also
- * creates a temporary directory to hold a .Xauthority
- *
- * Returns: TRUE if it suceeds, FALSE if it fails.
- */
-static int
-prepare_xauth (GksuContext *context)
-{
-  gchar *display = NULL;
-  gchar *xauth = NULL;
-
-  display = g_strdup (getenv ("DISPLAY"));
-  xauth = get_xauth_token (context, display);
-  if (xauth == NULL)
-    {
-      g_free (display);
-      return FALSE;
-    }
-
-  /* If xauth is the empty string, then try striping the
-   * hostname part of the DISPLAY string for getting the
-   * auth token; this is needed for ssh-forwarded usage
-   */
-  if (!strcmp ("", xauth))
-    {
-      gchar *cut_display = NULL;
-
-      g_free (xauth);
-      cut_display = g_strdup (g_strrstr (display, ":"));
-      xauth = get_xauth_token (context, cut_display);
-
-      g_free (display);
-      display = cut_display;
-    }
-
-  context->xauth = xauth;
-  context->display = display;
-
-  if (context->debug)
-    {
-      fprintf(stderr,
-	      "final xauth: -%s-\n"
-	      "final display: -%s-\n",
-	      context->xauth, context->display);
-    }
-
-  return TRUE;
-}
-
-/* Write all of buf, even if write(2) is interrupted. */
-static ssize_t
-full_write (int d, const char *buf, size_t nbytes)
-{
-  ssize_t r, w = 0;
-
-  /* Loop until nbytes of buf have been written. */
-  while (w < nbytes) {
-    /* Keep trying until write succeeds without interruption. */
-    do {
-      r = write(d, buf + w, nbytes - w);
-    } while (r < 0 && errno == EINTR);
-
-    if (r < 0) {
-      return -1;
-    }
-
-    w += r;
-  }
-
-  return w;
-}
-
-static gboolean
-copy (const char *fn, const char *dir)
-{
-  int in, out;
-  int r;
-  char *newfn;
-  char buf[BUFSIZ] = "";
-
-  newfn = g_strdup_printf("%s/.Xauthority", dir);
-
-  out = open(newfn, O_WRONLY | O_CREAT | O_EXCL, 0600);
-  if (out == -1)
-    {
-      if (errno == EEXIST)
-	fprintf (stderr,
-		 "Impossible to create the .Xauthority file: a file "
-		 "already exists. This might be a security issue; "
-		 "please investigate.");
-      else
-	fprintf (stderr,
-		 "Error copying '%s' to '%s': %s",
-		 fn, dir, strerror(errno));
-
-      return FALSE;
-    }
-
-  in = open(fn, O_RDONLY);
-  if (in == -1)
-    {
-      fprintf (stderr,
-	       "Error copying '%s' to '%s': %s",
-	       fn, dir, strerror(errno));
-      return FALSE;
-    }
-
-  while ((r = read(in, buf, BUFSIZ)) > 0)
-    {
-      if (full_write(out, buf, r) == -1)
-	{
-	  fprintf (stderr,
-		   "Error copying '%s' to '%s': %s",
-		   fn, dir, strerror(errno));
-	  return FALSE;
-	}
-    }
-
-  if (r == -1)
-    {
-      fprintf (stderr,
-	       "Error copying '%s' to '%s': %s",
-	       fn, dir, strerror(errno));
-      return FALSE;
-    }
-
-  return TRUE;
-}
-
-static gboolean
-sudo_prepare_xauth (GksuContext *context)
-{
-  gchar template[] = "/tmp/" PACKAGE "-XXXXXX";
-  gboolean error_copying = FALSE;
-  gchar *xauth = NULL;
-
-  context->dir = g_strdup (mkdtemp(template));
-  if (!context->dir)
-    {
-      fprintf (stderr, strerror(errno));
-      return FALSE;
-    }
-
-  xauth = g_strdup(g_getenv ("XAUTHORITY"));
-  if (xauth == NULL)
-    xauth = g_strdup_printf ("%s/.Xauthority", g_get_home_dir());
-
-  error_copying = !copy (xauth, context->dir);
-  g_free (xauth);
-
-  if (error_copying)
-    return FALSE;
-
-  return TRUE;
-}
-
-static void
-sudo_reset_xauth (GksuContext *context, gchar *xauth,
-		  gchar *xauth_env)
-{
-  /* reset the env var as it was before or clean it  */
-  if (xauth_env)
-    setenv ("XAUTHORITY", xauth_env, TRUE);
-  else
-    unsetenv ("XAUTHORITY");
-
-  if (context->debug)
-    fprintf (stderr, "xauth: %s\nxauth_env: %s\ndir: %s\n",
-	     xauth, xauth_env, context->dir);
-
-  unlink (xauth);
-  rmdir (context->dir);
-
-  g_free (xauth);
-}
-
-static void
-startup_notification_initialize (GksuContext *context)
-{
-  SnDisplay *sn_display;
-  sn_display = sn_display_new (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
-			       NULL, NULL);
-  context->sn_context = sn_launcher_context_new (sn_display, gdk_screen_get_number (gdk_display_get_default_screen (gdk_display_get_default ())));
-  sn_launcher_context_set_description (context->sn_context, _("Granting Rights"));
-  sn_launcher_context_set_name (context->sn_context, g_get_prgname ());
-}
-
-/**
- * gksu_context_new
- *
- * This function should be used when creating a new #GksuContext to
- * pass to gksu_su_full or gksu_sudo_full. The #GksuContext must be
- * freed with gksu_context_free.
- *
- * Returns: a newly allocated #GksuContext
- */
-GksuContext*
-gksu_context_new ()
-{
-  GksuContext *context;
-
-  context = g_new (GksuContext, 1);
-
-  context->xauth = NULL;
-  context->dir = NULL;
-  context->display = NULL;
-
-  context->gconf_client = gconf_client_get_default ();
-
-  context->sudo_mode = FALSE;
-
-  context->user = g_strdup ("root");
-  context->command = NULL;
-
-  context->login_shell = FALSE;
-  context->keep_env = FALSE;
-
-  context->description = NULL;
-  context->message = NULL;
-  context->alert = NULL;
-  context->grab = TRUE;
-  context->always_ask_password = FALSE;
-
-  context->debug = FALSE;
-
-  context->sn_context = NULL;
-  context->sn_id = NULL;
-  
-  context->ref_count = 1;
-
-  get_configuration_options (context);
-  startup_notification_initialize (context);
-
-  return context;
-}
-
-/**
- * gksu_context_set_user:
- * @context: the #GksuContext you want to modify
- * @username: the target username
- *
- * Sets up what user the command will be run as. The default
- * is root, but you can run the command as any user.
- *
- */
-void
-gksu_context_set_user (GksuContext *context, gchar *username)
-{
-  g_assert (username != NULL);
-
-  if (context->user)
-    g_free (context->user);
-  context->user = g_strdup (username);
-}
-
-/**
- * gksu_context_get_user:
- * @context: the #GksuContext from which to grab the information
- *
- * Gets the user the command will be run as, as set
- * by gksu_context_set_user.
- *
- * Returns: a string with the user or NULL if not set.
- */
-const gchar*
-gksu_context_get_user (GksuContext *context)
-{
-  return context->user;
-}
-
-/**
- * gksu_context_set_command:
- * @context: the #GksuContext you want to modify
- * @command: the command that shall be ran
- *
- * Sets up what command will run with the target user.
- *
- */
-void
-gksu_context_set_command (GksuContext *context, gchar *command)
-{
-  g_assert (command != NULL);
-
-  if (context->command)
-    g_free (context->command);
-  context->command = g_strdup (command);
-
-  /* startup notification */
-  sn_launcher_context_set_binary_name (context->sn_context,
-				       command);
-}
-
-/**
- * gksu_context_get_command:
- * @context: the #GksuContext from which to grab the information
- *
- * Gets the command that will be run, as set by
- * gksu_context_set_command.
- *
- * Returns: a string with the command or NULL if not set.
- */
-const gchar*
-gksu_context_get_command (GksuContext *context)
-{
-  return context->command;
-}
-
-/**
- * gksu_context_set_login_shell:
- * @context: the #GksuContext you want to modify
- * @value: TRUE or FALSE
- *
- * Should the shell in which the command will be run be
- * a login shell?
- */
-void
-gksu_context_set_login_shell (GksuContext *context, gboolean value)
-{
-  context->login_shell = value;
-}
-
-/**
- * gksu_context_get_login_shell:
- * @context: the #GksuContext from which to grab the information
- *
- * Finds out if the shell created by the underlying su process
- * will be a login shell.
- *
- * Returns: TRUE if the shell will be a login shell, FALSE otherwise.
- */
-gboolean
-gksu_context_get_login_shell (GksuContext *context)
-{
-  return context->login_shell;
-}
-
-/**
- * gksu_context_set_keep_env:
- * @context: the #GksuContext you want to modify
- * @value: TRUE or FALSE
- *
- * Should the environment be kept as it is? Defaults to
- * TRUE. Notice that setting this to FALSE may cause the
- * X authorization stuff to fail.
- */
-void
-gksu_context_set_keep_env (GksuContext *context, gboolean value)
-{
-  context->keep_env = value;
-}
-
-/**
- * gksu_context_get_keep_env:
- * @context: the #GksuContext from which to grab the information
- *
- * Finds out if the environment in which the program will be
- * run will be reset.
- *
- * Returns: TRUE if the environment is going to be kept,
- * FALSE otherwise.
- */
-gboolean
-gksu_context_get_keep_env (GksuContext *context)
-{
-  return context->keep_env;
-}
-
-/**
- * gksu_context_set_description:
- * @context: the #GksuContext you want to modify
- * @description: a string to set the description for
- *
- * Set the nice name for the action that is being run that the window
- * that asks for the password will have.  This is only meant to be
- * used if the default window is used, of course.
- */
-void
-gksu_context_set_description (GksuContext *context, gchar *description)
-{
-  if (context->description)
-    g_free (context->description);
-  context->description = g_strdup (description);
-}
-
-/**
- * gksu_context_get_description:
- * @context: the #GksuContext you want to get the description from.
- *
- * Get the description that the window will have when the
- * default function for requesting the password is
- * called.
- *
- * Returns: a string with the description or NULL if not set.
- */
-gchar*
-gksu_context_get_description (GksuContext *context)
-{
-  return context->description;
-}
-
-/**
- * gksu_context_set_message:
- * @context: the #GksuContext you want to modify
- * @message: a string to set the message for
- *
- * Set the message that the window that asks for the password will have.
- * This is only meant to be used if the default window is used, of course.
- */
-void
-gksu_context_set_message (GksuContext *context, gchar *message)
-{
-  if (context->message)
-    g_free (context->message);
-  context->message = g_strdup (message);
-}
-
-/**
- * gksu_context_get_message:
- * @context: the #GksuContext you want to get the message from.
- *
- * Get the message that the window will have when the
- * default function for requesting the password is
- * called.
- *
- * Returns: a string with the message or NULL if not set.
- */
-gchar*
-gksu_context_get_message (GksuContext *context)
-{
-  return context->message;
-}
-
-/**
- * gksu_context_set_alert:
- * @context: the #GksuContext you want to modify
- * @alert: a string to set the alert for
- *
- * Set the alert that the window that asks for the password will have.
- * This is only meant to be used if the default window is used, of course.
- * This alert should be used to display messages such as 'incorrect password',
- * for instance.
- */
-void
-gksu_context_set_alert (GksuContext *context, gchar *alert)
-{
-  if (context->alert)
-    g_free (context->alert);
-  context->alert = g_strdup (alert);
-}
-
-/**
- * gksu_context_get_alert:
- * @context: the #GksuContext you want to get the alert from.
- *
- * Get the alert that the window will have when the
- * default function for requesting the password is
- * called.
- *
- * Returns: a string with the alert or NULL if not set.
- */
-gchar*
-gksu_context_get_alert (GksuContext *context)
-{
-  return context->alert;
-}
-
-/**
- * gksu_context_set_debug:
- * @context: the #GksuContext you want to modify
- * @value: TRUE or FALSE
- *
- * Set up if debuging information should be printed.
- */
-void
-gksu_context_set_grab (GksuContext *context, gboolean value)
-{
-  context->grab = value;
-}
-
-/**
- * gksu_context_get_grab:
- * @context: the #GksuContext you want to ask whether a grab will be done.
- *
- * Returns TRUE if gksu has been asked to do a grab on keyboard and mouse
- * when asking for the password.
- *
- * Returns: TRUE if yes, FALSE otherwise.
- */
-gboolean
-gksu_context_get_grab (GksuContext *context)
-{
-  return context->grab;
-}
-
-/**
- * gksu_context_set_always_ask_password:
- * @context: the #GksuContext you want to modify
- * @value: TRUE or FALSE
- *
- * Set up if gksu should always ask for a password. Notice that this
- * will only work when passwords are cached, as done by gnome-keyring
- * for gksu's su mode and by sudo for gksu's sudo mode, but will have no
- * effect if su or sudo are set up to not require the password at all.
- */
-void
-gksu_context_set_always_ask_password (GksuContext *context, gboolean value)
-{
-  context->always_ask_password = value;
-}
-
-/**
- * gksu_context_get_always_ask_password:
- * @context: the #GksuContext you want to ask whether a grab will be done.
- *
- * Returns TRUE if gksu has been asked to always ask for a password 
- * (even if sudo or gnome-keyring have cached it)
- *
- * Returns: TRUE if yes, FALSE otherwise.
- */
-gboolean
-gksu_context_get_always_ask_password (GksuContext *context)
-{
-   return context->always_ask_password;
-}
-
-
-/**
- * gksu_context_set_launcher_context:
- * @context: the #GksuContext you want to set the sn context in
- * @sn_context: the #SnLauncherContext you want to set
- *
- * Tell libgksu to use the given #SnLauncherContext for startup notification.
- * Currently the library will use this to set DESKTOP_STARTUP_ID in the
- * environment of the child and to issue initiate and complete events.
- * Notice that you don't need to use this function unless you want to
- * override gksu's default behavior on startup notification, since the
- * library will create its own context.
- *
- * Returns: the #SnLauncherContext which is set, or NULL if none was set
- */
-void
-gksu_context_set_launcher_context (GksuContext *context,
-				   SnLauncherContext *sn_context)
-{
-  if (context->sn_context)
-    sn_launcher_context_unref (context->sn_context);
-  context->sn_context = sn_context;
-}
-
-/**
- * gksu_context_get_launcher_context:
- * @context: the #GksuContext you want to get the sn context from
- *
- * Gets the current startup notification launcher context
- *
- * Returns: the #SnLauncherContext which is set, or NULL if none was set
- */
-SnLauncherContext*
-gksu_context_get_launcher_context (GksuContext *context)
-{
-  return context->sn_context;
-}
-
-/**
- * gksu_context_set_launcher_id:
- * @context: the #GksuContext you want to set the sn id in
- * @sn_context: the sn_id you want to set, as a #gchar
- */
-void
-gksu_context_set_launcher_id (GksuContext *context,
-			      gchar *sn_id)
-{
-  if (context->sn_id)
-    g_free (context->sn_id);
-  context->sn_id = g_strdup(sn_id);
-}
-
-/**
- * gksu_context_launch_initiate:
- * @context: the #GksuContext you want to initiate the launch for
- *
- * Initiates the launch, as far as Startup Notification is concerned;
- * This will only be used internally, usually.
- */
-static void
-gksu_context_launch_initiate (GksuContext *context)
-{
-  gchar *sid = NULL;
-  guint32 launch_time = gdk_x11_display_get_user_time ((GdkDisplay*)GDK_DISPLAY());
-  static gboolean initiated = FALSE;
-
-  if (!initiated)
-    initiated = TRUE;
-  else
-    return;
-
-  sn_launcher_context_initiate (context->sn_context,
-				g_get_prgname (),
-				gksu_context_get_command (context),
-				launch_time);
-
-  sid = g_strdup_printf ("%s", sn_launcher_context_get_startup_id (context->sn_context));
-  gksu_context_set_launcher_id (context, sid);
-
-  if (context->debug)
-    fprintf (stderr, "STARTUP_ID: %s\n", sid);
-  setenv ("DESKTOP_STARTUP_ID", sid, TRUE);
-  g_free(sid);
-}
-
-/**
- * gksu_context_launch_complete:
- * @context: the #GksuContext you want to complete the launch for
- *
- * Completes the launch, as far as Startup Notification is concerned;
- * This will only be used internally, usually.
- */
-static void
-gksu_context_launch_complete (GksuContext *context)
-{
-  sn_launcher_context_complete(context->sn_context);
-}
-
-/**
- * gksu_context_set_debug:
- * @context: the #GksuContext you want to modify
- * @value: TRUE or FALSE
- *
- * Set up if debuging information should be printed.
- */
-void
-gksu_context_set_debug (GksuContext *context, gboolean value)
-{
-  context->debug = value;
-}
-
-/**
- * gksu_context_get_debug:
- * @context: the #GksuContext from which to grab the information
- *
- * Finds out if the library is configured to print debuging
- * information.
- *
- * Returns: TRUE if it is, FALSE otherwise.
- */
-gboolean
-gksu_context_get_debug (GksuContext *context)
-{
-  return context->debug;
-}
-
-/**
- * gksu_context_free
- * @context: the #GksuContext to be freed.
- *
- * Frees the given #GksuContext.
- */
-void
-gksu_context_free (GksuContext *context)
-{
-  g_free (context->xauth);
-  g_free (context->dir);
-  g_free (context->display);
-
-  g_object_unref (context->gconf_client);
-
-  g_free (context->description);
-  g_free (context->message);
-
-  g_free (context->user);
-  g_free (context->command);
-
-  g_free (context);
-}
-
-/**
- * gksu_context_ref
- * @context: A #GksuContext struct.
- *
- * Increments the reference count of the given #GksuContext.
- */
-GksuContext*
-gksu_context_ref (GksuContext *context)
-{
-  context->ref_count++;
-  return context;
-}
-
-/**
- * gksu_context_unref
- * @context: A #GksuContext struct.
- *
- * Decrements the reference count of the given #GksuContext struct,
- * freeing it if the reference count falls to zero.
- */
-void
-gksu_context_unref (GksuContext *context)
-{
-  if (--context->ref_count == 0)
-    {
-        gksu_context_free (context);
-    }
-}
-
-GType
-gksu_context_get_type (void)
-{
-  static GType type_gksu_context = 0;
-
-  if (!type_gksu_context)
-    type_gksu_context = g_boxed_type_register_static
-      ("GksuContext", 
-       (GBoxedCopyFunc) gksu_context_ref,
-       (GBoxedFreeFunc) gksu_context_unref);
-
-  return type_gksu_context;
-}
-
-
-/**
- * gksu_su_full:
- * @context: a #GksuContext
- * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
- * requesting a password is necessary; it may be NULL, in which case
- * the standard password request dialog will be used
- * @ask_pass_data: a #gpointer with user data to be passed to the
- * #GksuAskPasswordFunc
- * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
- * when the command is being run without the need for requesting
- * a password; it will only be called if the display-no-pass-info
- * gconf key is enabled; NULL will have the standard dialog be shown
- * @pass_not_needed_data: a #gpointer with the user data to be passed to the
- * #GksuPasswordNotNeededFunc
- * @error: a #GError object to be filled with the error code or NULL
- *
- * This is a compatibility shim over gksu_su_fuller, which, for
- * compatibility reasons, lacks the 'exit_status' argument. You should
- * check the documentation for gksu_su_fuller for information about
- * the arguments.
- *
- * Returns: TRUE if all went fine, FALSE if failed
- */
-
-gboolean
-gksu_su_full (GksuContext *context,
-	      GksuAskPassFunc ask_pass,
-	      gpointer ask_pass_data,
-	      GksuPassNotNeededFunc pass_not_needed,
-	      gpointer pass_not_needed_data,
-	      GError **error)
-{
-  return gksu_su_fuller(context,
-  			ask_pass, ask_pass_data,
-			pass_not_needed, pass_not_needed_data,
-			NULL, error);
-}
-
-
-/**
- * gksu_su_fuller:
- * @context: a #GksuContext
- * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
- * requesting a password is necessary; it may be NULL, in which case
- * the standard password request dialog will be used
- * @ask_pass_data: a #gpointer with user data to be passed to the
- * #GksuAskPasswordFunc
- * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
- * when the command is being run without the need for requesting
- * a password; it will only be called if the display-no-pass-info
- * gconf key is enabled; NULL will have the standard dialog be shown
- * @pass_not_needed_data: a #gpointer with the user data to be passed to the
- * #GksuPasswordNotNeededFunc
- * @exit_status: an optional pointer to a #gint8 which will be filled with
- * the exit status of the child process
- * @error: a #GError object to be filled with the error code or NULL
- *
- * This could be considered one of the main functions in GKSu.
- * it is responsible for doing the 'user changing' magic calling
- * the #GksuAskPassFunc function to request a password if needed.
- * and the #GksuPassNotNeededFunc function if a password won't be
- * needed, so the application has the oportunity of warning the user
- * what it's doing.
- *
- * This function uses su as backend.
- *
- * Returns: TRUE if all went fine, FALSE if failed
- */
-gboolean
-gksu_su_fuller (GksuContext *context,
-	        GksuAskPassFunc ask_pass,
-	        gpointer ask_pass_data,
-	        GksuPassNotNeededFunc pass_not_needed,
-	        gpointer pass_not_needed_data,
-	        gint8 *exit_status,
-	        GError **error)
-{
-  GQuark gksu_quark;
-  int i = 0;
-
-  gchar auxcommand[] = PREFIX "/lib/" PACKAGE "/gksu-run-helper";
-
-  int fdpty;
-  pid_t pid;
-
-  context->sudo_mode = FALSE;
-
-  gksu_quark = g_quark_from_string (PACKAGE);
-
-  if (!context->command)
-    {
-      g_set_error (error, gksu_quark, GKSU_ERROR_NOCOMMAND,
-		   _("gksu_run needs a command to be run, "
-		     "none was provided."));
-      return FALSE;
-    }
-
-  if (!context->user)
-    context->user = g_strdup ("root");
-
-  if (!g_file_test (auxcommand, G_FILE_TEST_IS_EXECUTABLE))
-    {
-      g_set_error (error, gksu_quark, GKSU_ERROR_HELPER,
-		   _("The gksu-run-helper command was not found or "
-		     "is not executable."));
-      return FALSE;
-    }
-
-  if (!prepare_xauth (context))
-    {
-      g_set_error (error, gksu_quark, GKSU_ERROR_XAUTH,
-		   _("Unable to copy the user's Xauthorization file."));
-      return FALSE;
-    }
-
-  if (context->sn_context)
-    gksu_context_launch_initiate (context);
-
-  pid = forkpty(&fdpty, NULL, NULL, NULL);
-  if (pid == 0)
-    {
-      gchar **cmd = g_malloc (sizeof(gchar*)*7);
-
-      setsid();   // make us session leader
-      cmd[i] = g_strdup ("/bin/su"); i++;
-      if (context->login_shell)
-	{
-	  cmd[i] = g_strdup ("-"); i++;
-	}
-      cmd[i] = g_strdup (context->user); i++;
-      if (context->keep_env)
-	{
-	  cmd[i] = g_strdup ("-p"); i++;
-	}
-      cmd[i] = g_strdup ("-c"); i++;
-
-      /* needs to get X authorization prior to running the program */
-      cmd[i] = g_strdup_printf ("%s \"%s\"", auxcommand,
-				context->command); i++;
-
-      cmd[i] = NULL;
-
-      /* executes the command */
-      if (execv (cmd[0], cmd) == -1)
-	{
-	  fprintf (stderr,
-		   "Unable to run /bin/su: %s",
-		   strerror(errno));
-	}
-
-      for (i = 0 ; cmd[i] != NULL ; i++)
-	g_free (cmd[i]);
-      g_free(cmd);
-    }
-  else if (pid == -1)
-    {
-      g_set_error (error, gksu_quark, GKSU_ERROR_FORK,
-		   _("Failed to fork new process: %s"),
-		   strerror(errno));
-      return FALSE;
-    }
-  else
-    {
-      fd_set rfds;
-
-      struct timeval tv;
-
-      struct passwd *pwd = NULL;
-      gint target_uid = -1;
-      gint my_uid = 0;
-
-      gchar buf[256] = {0};
-      gint status;
-
-      gchar *password = NULL;
-      gchar *cmdline = NULL;
-      gboolean password_needed = FALSE;
-      gboolean used_gnome_keyring = FALSE;
-
-      my_uid = getuid();
-      pwd = getpwnam (context->user);
-      if (pwd)
-	target_uid = pwd->pw_uid;
-
-      if (ask_pass == NULL)
-	{
-	  ask_pass = su_ask_password;
-	}
-
-      if (pass_not_needed == NULL)
-	{
-	  pass_not_needed = no_pass;
-	}
-
-      /* no need to ask for password if we're already root */
-      if (my_uid != target_uid && my_uid)
-	{
-	  gint count;
-	  struct termios tio;
-
-	  read (fdpty, buf, 255);
-	  if (context->debug)
-	    fprintf (stderr, "gksu_context_run: buf: -%s-\n", buf);
-
-	  /* make sure we notice that ECHO is turned off, if it gets
-	     turned off */
-	  tcgetattr (fdpty, &tio);
-	  for (count = 0; (tio.c_lflag & ECHO) && count < 15; count++)
-	    {
-	      usleep (1000);
-	      tcgetattr (fdpty, &tio);
-	    }
-
-	  if (!(tio.c_lflag & ECHO))
-	    {
-	      gboolean prompt_grab;
-	      prompt_grab = gconf_client_get_bool (context->gconf_client, BASE_PATH "prompt",
-						   NULL);
-
-	      if (prompt_grab)
-		gksu_prompt_grab (context);
-
-              /* try to get the password from the GNOME Keyring first, but
-	       * only if we have not been requested to always ask for the
-	       * password
-	       */
-	      if (!context->always_ask_password)
-	        password = get_gnome_keyring_password (context);
-	      if (password == NULL)
-		{
-		  password = ask_pass (context, buf, ask_pass_data, error);
-		  if (context->debug)
-		    {
-		      fprintf (stderr, "no password on keyring\n");
-		      if (password == NULL)
-			fprintf (stderr, "no password from ask_pass!\n");
-		    }
-		}
-	      else
-		{
-		  if (context->debug)
-		    fprintf (stderr, "password from keyring found\n");
-		  used_gnome_keyring = TRUE;
-		}
-	      if (password == NULL || (error && (*error)))
-		{
-		  if (context->debug)
-		    fprintf (stderr, "gksu_su_full: problem getting password - getting out\n");
-		  if (context->debug && error)
-		    fprintf (stderr, "error: %s\n", (*error)->message);
-		  nullify_password (password);
-		  return TRUE;
-		}
-
-	      write (fdpty, password, strlen(password) + 1);
-	      write (fdpty, "\n", 1);
-	      password_needed = TRUE;
-	    }
-	}
-
-      if (context->debug)
-	fprintf (stderr, "DEBUG (run:after-pass) buf: -%s-\n", buf);
-      if (strncmp (buf, "gksu", 4) && strncmp (buf, "su", 2))
-	{
-	  /* drop the \n echoed on password entry if su did request
-	     a password */
-	  if (password_needed)
-	    read (fdpty, buf, 255);
-	  if (context->debug)
-	    fprintf (stderr, "DEBUG (run:post-after-pass) buf: -%s-\n", buf);
-	  read (fdpty, buf, 255);
-	  if (context->debug)
-	    fprintf (stderr, "DEBUG (run:post-after-pass) buf: -%s-\n", buf);
-	}
-
-      FD_ZERO (&rfds);
-      FD_SET (fdpty, &rfds);
-      tv.tv_sec = 1;
-      tv.tv_usec = 0;
-      int loop_count = 0;
-      while (TRUE)
-	{
-	  int retval = 0;
-
-	  if (!strncmp (buf, "su", 2))
-	    {
-	      gchar **strings;
-
-	      if (password)
-		{
-		  nullify_password (password);
-		  unset_gnome_keyring_password (context);
-		}
-
-	      strings = g_strsplit (buf, ":", 2);
-	      if (strings[1] && !strncmp (strings[1], " Authentication failure", 23))
-		{
-		  if (used_gnome_keyring)
-		    g_set_error (error, gksu_quark,
-				 GKSU_ERROR_WRONGAUTOPASS,
-				 _("Wrong password got from keyring."));
-		  else
-		    g_set_error (error, gksu_quark,
-				 GKSU_ERROR_WRONGPASS,
-				 _("Wrong password."));
-		}
-	      g_strfreev (strings);
-
-	      if (context->debug)
-		fprintf (stderr, "DEBUG (auth_failed) buf: -%s-\n", buf);
-
-	      break;
-	    }
-	  else if (!strncmp (buf, "gksu: waiting", 13))
-	    {
-	      gchar *line;
-
-	      if (password)
-		{
-		  set_gnome_keyring_password (context, password);
-		  nullify_password (password);
-		}
-
-	      if (context->debug)
-		fprintf (stderr, "DEBUG (gksu: waiting) buf: -%s-\n", buf);
-
-	      line = g_strdup_printf ("gksu-run: %s\n", context->display);
-	      write (fdpty, line, strlen(line));
-	      g_free (line);
-
-	      line = g_strdup_printf ("gksu-run: %s\n", context->sn_id);
-	      write (fdpty, line, strlen(line));
-	      g_free (line);
-
-	      line = g_strdup_printf ("gksu-run: %s\n", context->xauth);
-	      write (fdpty, line, strlen(line));
-	      g_free (line);
-
-	      tcdrain (fdpty);
-
-	      bzero (buf, 256);
-	      read (fdpty, buf, 255);
-
-	      break;
-	    }
-
-	  retval = select (fdpty + 1, &rfds, NULL, NULL, &tv);
-	  if ((loop_count > 50) || (!retval))
-	    {
-	      gchar *emsg = NULL;
-	      gchar *converted_str = NULL;
-	      GError *converr = NULL;
-
-	      if (password)
-		nullify_password (password);
-
-	      converted_str = g_locale_to_utf8 (buf, -1, NULL, NULL, &converr);
-	      if (converr)
-		{
-		  g_warning (_("Failed to communicate with "
-			       "gksu-run-helper.\n\n"
-			       "Received:\n"
-			       " %s\n"
-			       "While expecting:\n"
-			       " %s"), buf, "gksu: waiting");
-		  emsg = g_strdup_printf (_("Failed to communicate with "
-					    "gksu-run-helper.\n\n"
-					    "Received bad string "
-					    "while expecting:\n"
-					    " %s"), "gksu: waiting");
-		  g_error_free (converr);
-		}
-	      else
-		emsg = g_strdup_printf (_("Failed to communicate with "
-					  "gksu-run-helper.\n\n"
-					  "Received:\n"
-					  " %s\n"
-					  "While expecting:\n"
-					  " %s"), converted_str, "gksu: waiting");
-	      g_free (converted_str);
-
-	      g_set_error (error, gksu_quark, GKSU_ERROR_HELPER, emsg);
-	      g_free (emsg);
-
-	      if (context->debug)
-		fprintf (stderr, "DEBUG (failed!) buf: -%s-\n", buf);
-
-	      return FALSE;
-	    }
-	  else if (retval == -1)
-	    {
-	      if (context->debug)
-		fprintf (stderr, "DEBUG (select failed!) buf: %s\n", buf);
-	      return FALSE;
-	    }
-
-	  read (fdpty, buf, 255);
-	  if (context->debug)
-	    fprintf (stderr, "DEBUG (run:after-pass) buf: -%s-\n", buf);
-	  loop_count++;
-	}
-
-      if (!password_needed || used_gnome_keyring)
-	{
-	  gboolean should_display;
-
-	  should_display = gconf_client_get_bool (context->gconf_client,
-						  BASE_PATH "display-no-pass-info", NULL);
-
-	  /* configuration tells us to show this message */
-	  if (should_display)
-	    {
-	      if (context->debug)
-		fprintf (stderr, "Calling pass_not_needed window...\n");
-	      pass_not_needed (context, pass_not_needed_data);
-	      /* make sure it is displayed */
-	      while (gtk_events_pending ())
-		gtk_main_iteration ();
-	    }
-	}
-
-      cmdline = g_strdup("bin/su");
-      /* wait for the child process to end or become something other
-	 than su */
-      pid_t pid_exited;
-      while ((!(pid_exited = waitpid (pid, &status, WNOHANG))) &&
-	     (g_str_has_suffix(cmdline, "bin/su")))
-	{
-	  if (cmdline)
-	    g_free (cmdline);
-	  cmdline = get_process_name (pid);
-	  usleep(100000);
-	}
-
-      if (context->sn_context)
-	gksu_context_launch_complete (context);
-
-      bzero(buf, 256);
-      while (read (fdpty, buf, 255) > 0)
-	{
-	  fprintf (stderr, "%s", buf);
-	  bzero(buf, 256);
-	}
-
-      if (pid_exited != pid)
-	waitpid(pid, &status, 0);
-
-      if (exit_status)
-      {
-      	if (WIFEXITED(status)) {
-      	  *exit_status = WEXITSTATUS(status);
-	} else if (WIFSIGNALED(status)) {
-	  *exit_status = -1;
-	}
-      }
-
-      if (WEXITSTATUS(status))
-	{
-	  if(cmdline)
-	    {
-	      /* su already exec()ed something else, don't report
-	       * exit status errors in that case
-	       */
-	      if (!g_str_has_suffix (cmdline, "su"))
-		{
-		  g_free (cmdline);
-		  return FALSE;
-		}
-	      g_free (cmdline);
-	    }
-
-	  if (error == NULL)
-	    g_set_error (error, gksu_quark,
-			 GKSU_ERROR_CHILDFAILED,
-			 _("su terminated with %d status"),
-			 WEXITSTATUS(status));
-	}
-    }
-
-  if (error)
-    return FALSE;
-
-  return TRUE;
-}
-
-/**
- * gksu_su
- * @command_line: the command line that will be executed as other user
- * @error: a #GError to be set with the error condition, if an error
- * happens
- *
- * This function is a wrapper for gksu_su_run_full. It will call it
- * without giving the callback functions, which leads to the standard
- * ones being called. A simple #GksuContext is created to hold the
- * user name and the command.
- *
- * Returns: TRUE if all went well, FALSE if an error happend.
- */
-gboolean
-gksu_su (gchar *command_line, GError **error)
-{
-  GksuContext *context = gksu_context_new ();
-  gboolean retval;
-
-  context->command = g_strdup (command_line);
-  context->user = g_strdup ("root");
-  retval = gksu_su_full (context,
-			 NULL, NULL,
-			 NULL, NULL,
-			 error);
-  gksu_context_free (context);
-  return retval;
-}
-
-static void
-read_line (int fd, gchar *buffer, int n)
-{
-  gint counter = 0;
-  gchar tmp[2] = {0};
-
-  for (; counter < (n - 1); counter++)
-    {
-      read (fd, tmp, 1);
-      if (tmp[0] == '\n')
-	break;
-      buffer[counter] = tmp[0];
-    }
-  buffer[counter+1] = '\0';
-}
-
-/**
- * gksu_sudo_full:
- * @context: a #GksuContext
- * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
- * requesting a password is necessary; it may be NULL, in which case
- * the standard password request dialog will be used
- * @ask_pass_data: a #gpointer with user data to be passed to the
- * #GksuAskPasswordFunc
- * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
- * when the command is being run without the need for requesting
- * a password; it will only be called if the display-no-pass-info
- * gconf key is enabled; NULL will have the standard dialog be shown
- * @pass_not_needed_data: a #gpointer with the user data to be passed to the
- * #GksuPasswordNotNeededFunc
- * @error: a #GError object to be filled with the error code or NULL
- *
- * This is a compatibility shim over gksu_sudo_fuller, which, for
- * compatibility reasons, lacks the 'exit_status' argument. You should
- * check the documentation for gksu_sudo_fuller for information about
- * the arguments.
- *
- * Returns: TRUE if all went fine, FALSE if failed
- */
-
-gboolean
-gksu_sudo_full (GksuContext *context,
-		GksuAskPassFunc ask_pass,
-		gpointer ask_pass_data,
-		GksuPassNotNeededFunc pass_not_needed,
-		gpointer pass_not_needed_data,
-		GError **error)
-{
-  return gksu_sudo_fuller(context,
-  			  ask_pass, ask_pass_data,
-			  pass_not_needed, pass_not_needed_data,
-			  NULL, error);
-}
-
-/**
- * gksu_sudo_fuller:
- * @context: a #GksuContext
- * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
- * requesting a password is necessary; it may be NULL, in which case
- * the standard password request dialog will be used
- * @ask_pass_data: a #gpointer with user data to be passed to the
- * #GksuAskPasswordFunc
- * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
- * when the command is being run without the need for requesting
- * a password; it will only be called if the display-no-pass-info
- * gconf key is enabled; NULL will have the standard dialog be shown
- * @pass_not_needed_data: a #gpointer with the user data to be passed to the
- * #GksuPasswordNotNeededFunc
- * @error: a #GError object to be filled with the error code or NULL
- * @exit_status: an optional pointer to a #gint8 which will be filled with
- * the exit status of the child process
- *
- * This could be considered one of the main functions in GKSu.
- * it is responsible for doing the 'user changing' magic calling
- * the #GksuAskPassFunc function to request a password if needed.
- * and the #GksuPassNotNeededFunc function if a password won't be
- * needed, so the application has the oportunity of warning the user
- * what it's doing.
- *
- * This function uses the sudo backend.
- *
- * Returns: TRUE if all went fine, FALSE if failed
- */
-gboolean
-gksu_sudo_fuller (GksuContext *context,
-		  GksuAskPassFunc ask_pass,
-		  gpointer ask_pass_data,
-		  GksuPassNotNeededFunc pass_not_needed,
-		  gpointer pass_not_needed_data,
-		  gint8 *exit_status,
-		  GError **error)
-{
-  char **cmd;
-  char buffer[256] = {0};
-  int argcount = 8;
-  int i, j;
-
-  GQuark gksu_quark;
-
-  gchar *xauth = NULL,
-    *xauth_env = NULL;
-
-  pid_t pid;
-  int status;
-  FILE *infile, *outfile;
-  int parent_pipe[2];	/* For talking to the parent */
-  int child_pipe[2];	/* For talking to the child */
-
-  context->sudo_mode = TRUE;
-
-  gksu_quark = g_quark_from_string (PACKAGE);
-
-  if (!context->command)
-    {
-      g_set_error (error, gksu_quark, GKSU_ERROR_NOCOMMAND,
-		   _("gksu_sudo_run needs a command to be run, "
-		     "none was provided."));
-      return FALSE;
-    }
-
-  if (!context->user)
-    context->user = g_strdup ("root");
-
-  if (ask_pass == NULL)
-    {
-      if (context->debug)
-	fprintf (stderr, "No ask_pass set, using default!\n");
-      ask_pass = su_ask_password;
-    }
-  if (pass_not_needed == NULL)
-    {
-      pass_not_needed = no_pass;
-    }
-
-  if (context->always_ask_password)
-    {
-       gint exit_status;
-       g_spawn_command_line_sync("/usr/bin/sudo -K", NULL, NULL, &exit_status, NULL);
-    }
-
-
-  /*
-     FIXME: need to set GError in a more detailed way
-  */
-  if (!sudo_prepare_xauth (context))
-    {
-      g_set_error (error, gksu_quark, GKSU_ERROR_XAUTH,
-		   _("Unable to copy the user's Xauthorization file."));
-      return FALSE;
-    }
-
-  /* sets XAUTHORITY */
-  xauth = g_strdup_printf ("%s/.Xauthority", context->dir);
-  xauth_env = getenv ("XAUTHORITY");
-  setenv ("XAUTHORITY", xauth, TRUE);
-  if (context->debug)
-    fprintf (stderr, "xauth: %s\n", xauth);
-
-  /* set startup id */
-  if (context->sn_context)
-    gksu_context_launch_initiate (context);
-
-  cmd = g_new (gchar *, argcount + 1);
-
-  argcount = 0;
-
-  /* sudo binary */
-  cmd[argcount] = g_strdup("/usr/bin/sudo");
-  argcount++;
-
-  if (!context->keep_env)
-    {
-      /* Make sudo set $HOME */
-      cmd[argcount] = g_strdup("-H");
-      argcount++;
-    }
-
-  /* Make sudo read from stdin */
-  cmd[argcount] = g_strdup("-S");
-  argcount++;
-
-  /* Make sudo use next arg as prompt */
-  cmd[argcount] = g_strdup("-p");
-  argcount++;
-
-  /* prompt */
-  cmd[argcount] = g_strdup("GNOME_SUDO_PASS");
-  argcount++;
-
-  /* Make sudo use the selected user */
-  cmd[argcount] = g_strdup("-u");
-  argcount++;
-
-  /* user */
-  cmd[argcount] = g_strdup(context->user);
-  argcount++;
-
-  /* sudo does not understand this if we do not use -H
-     weird.
-  */
-  if (!context->keep_env)
-    {
-      /* Make sudo stop processing options */
-      cmd[argcount] = g_strdup("--");
-      argcount++;
-    }
-
-  {
-    gchar *tmp_arg = g_malloc (sizeof(gchar)*1);
-    gboolean inside_quotes = FALSE;
-
-    tmp_arg[0] = '\0';
-
-    for (i = j = 0; ; i++)
-      {
-	if ((context->command[i] == '\'') && (context->command[i-1] != '\\'))
-	  {
-	    i = i + 1;
-	    inside_quotes = !inside_quotes;
-	  }
-
-	if ((context->command[i] == ' ' && inside_quotes == FALSE)
-	    || context->command[i] == '\0')
-	  {
-	    tmp_arg = g_realloc (tmp_arg, sizeof(gchar)*(j+1));
-	    tmp_arg[j] = '\0';
-	    cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
-	    cmd[argcount] = g_strdup (tmp_arg);
-
-	    g_free (tmp_arg);
-
-	    argcount = argcount + 1;
-	    j = 0;
-
-	    if (context->command[i] == '\0')
-	      break;
-
-	    tmp_arg = g_malloc (sizeof(gchar)*1);
-	    tmp_arg[0] = '\0';
-	  }
-	else
-	  {
-	    if (context->command[i] == '\\' && context->command[i+1] != '\\')
-	      i = i + 1;
-	    tmp_arg = g_realloc (tmp_arg, sizeof(gchar)*(j+1));
-	    tmp_arg[j] = context->command[i];
-	    j = j + 1;
-	  }
-      }
-  }
-  cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
-  cmd[argcount] = NULL;
-
-  if (context->debug)
-    {
-      for (i = 0; cmd[i] != NULL; i++)
-	fprintf (stderr, "cmd[%d]: %s\n", i, cmd[i]);
-    }
-
-  if ((pipe(parent_pipe)) == -1)
-    {
-      g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
-		   _("Error creating pipe: %s"),
-		   strerror(errno));
-      sudo_reset_xauth (context, xauth, xauth_env);
-      return FALSE;
-    }
-
-  if ((pipe(child_pipe)) == -1)
-    {
-      g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
-		   _("Error creating pipe: %s"),
-		   strerror(errno));
-      sudo_reset_xauth (context, xauth, xauth_env);
-      return FALSE;
-    }
-
-  pid = fork();
-  if (pid == -1)
-    {
-      g_set_error (error, gksu_quark, GKSU_ERROR_FORK,
-		   _("Failed to fork new process: %s"),
-		   strerror(errno));
-      sudo_reset_xauth (context, xauth, xauth_env);
-      return FALSE;
-    }
-  else if (pid == 0)
-    {
-      // Child
-      setsid();   // make us session leader
-      close(child_pipe[1]);
-      dup2(child_pipe[0], STDIN_FILENO);
-      dup2(parent_pipe[1], STDERR_FILENO);
-
-      execv(cmd[0], cmd);
-
-      g_set_error (error, gksu_quark, GKSU_ERROR_EXEC,
-		   _("Failed to exec new process: %s"),
-		   strerror(errno));
-      sudo_reset_xauth (context, xauth, xauth_env);
-      return FALSE;
-    }
-  else
-    {
-      gint counter = 0;
-      gchar *cmdline = NULL;
-
-      // Parent
-      close(parent_pipe[1]);
-
-      infile = fdopen(parent_pipe[0], "r");
-      if (!infile)
-	{
-	  g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
-		       _("Error opening pipe: %s"),
-		       strerror(errno));
-	  sudo_reset_xauth (context, xauth, xauth_env);
-	  return FALSE;
-	}
-
-      outfile = fdopen(child_pipe[1], "w");
-      if (!outfile)
-	{
-	  g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
-		       _("Error opening pipe: %s"),
-		       strerror(errno));
-	  sudo_reset_xauth (context, xauth, xauth_env);
-	  return FALSE;
-	}
-
-      /*
-	we are expecting to receive a GNOME_SUDO_PASS
-	if we don't there are two possibilities: an error
-	or a password is not needed
-      */
-      fcntl (parent_pipe[0], F_SETFL, O_NONBLOCK);
-
-      { /* no matter if we can read, since we're using
-	   O_NONBLOCK; this is just to avoid the prompt
-	   showing up after the read */
-	fd_set rfds;
-	struct timeval tv;
-
-	FD_ZERO(&rfds);
-	FD_SET(parent_pipe[0], &rfds);
-	tv.tv_sec = 1;
-	tv.tv_usec = 0;
-
-	select (parent_pipe[0] + 1, &rfds, NULL, NULL, &tv);
-      }
-
-      /* Try hard to find the prompt; it may happen that we're
-       * seeing sudo's lecture, or that some pam module is spitting
-       * debugging stuff at the screen
-       */
-      for (counter = 0; counter < 50; counter++)
-	{
-	  if (strncmp (buffer, "GNOME_SUDO_PASS", 15) == 0)
-	    break;
-
-	  read_line (parent_pipe[0], buffer, 256);
-
-	  if (context->debug)
-	    fprintf (stderr, "buffer: -%s-\n", buffer);
-
-	  usleep(1000);
-	}
-
-      if (context->debug)
-	fprintf (stderr, "brute force GNOME_SUDO_PASS ended...\n");
-
-      if (strncmp(buffer, "GNOME_SUDO_PASS", 15) == 0)
-	{
-	  gchar *password = NULL;
-	  gboolean prompt_grab;
-
-	  if (context->debug)
-	    fprintf (stderr, "Yeah, we're in...\n");
-
-	  prompt_grab = gconf_client_get_bool (context->gconf_client, BASE_PATH "prompt",
-						   NULL);
-	  if (prompt_grab)
-	    gksu_prompt_grab (context);
-
-	  password = ask_pass (context, _("Password: "),
-			       ask_pass_data, error);
-	  if (password == NULL || (*error))
-	    {
-	      nullify_password (password);
-	      return FALSE;
-	    }
-
-	  usleep (1000);
-
-	  fprintf (outfile, "%s\n", password);
-	  fclose (outfile);
-
-	  nullify_password (password);
-
-	  /* turn NONBLOCK off */
-	  fcntl(parent_pipe[0], F_SETFL, fcntl(parent_pipe[0], F_GETFL) & ~O_NONBLOCK);
-	  /* ignore the first newline that comes right after sudo receives
-	     the password */
-	  fgets (buffer, 255, infile);
-	  /* this is the status we are interessted in */
-	  fgets (buffer, 255, infile);
-	}
-      else
-	{
-	  gboolean should_display;
-	  if (context->debug)
-	    fprintf (stderr, "No password prompt found; we'll assume we don't need a password.\n");
-
-          /* turn NONBLOCK off, also if have no prompt */
-          fcntl(parent_pipe[0], F_SETFL, fcntl(parent_pipe[0], F_GETFL) & ~O_NONBLOCK);
-
-	  should_display = gconf_client_get_bool (context->gconf_client,
-						  BASE_PATH "display-no-pass-info", NULL);
-
-	  /* configuration tells us to show this message */
-	  if (should_display)
-	    {
-	      if (context->debug)
-		fprintf (stderr, "Calling pass_not_needed window...\n");
-	      pass_not_needed (context, pass_not_needed_data);
-	      /* make sure it is displayed */
-	      while (gtk_events_pending ())
-		gtk_main_iteration ();
-	    }
-
-	  fprintf (stderr, "%s", buffer);
-	}
-
-      if (!strcmp (buffer, "Sorry, try again.\n"))
-	g_set_error (error, gksu_quark, GKSU_ERROR_WRONGPASS,
-		     _("Wrong password."));
-      else if (!strncmp (buffer, "Sorry, user ", 12))
-	g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
-		     _("The underlying authorization mechanism (sudo) "
-		       "does not allow you to run this program. Contact "
-		       "the system administrator."));
-      else
-	{
-	  gchar *haystack = buffer;
-	  gchar *needle;
-
-	  needle = g_strstr_len (haystack, strlen (haystack), " ");
-	  if (needle && (needle + 1))
-	    {
-	      needle += 1;
-	      if (!strncmp (needle, "is not in", 9))
-		g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
-			     _("The underlying authorization mechanism (sudo) "
-			       "does not allow you to run this program. Contact "
-			       "the system administrator."));
-	    }
-	}
-
-      cmdline = g_strdup("sudo");
-      /* wait for the child process to end or become something other
-	 than sudo */
-      pid_t pid_exited;
-      while ((!(pid_exited = waitpid (pid, &status, WNOHANG))) &&
-	     (g_str_has_suffix(cmdline, "sudo")))
-	{
-	  if (cmdline)
-	    g_free (cmdline);
-	  cmdline = get_process_name (pid);
-	  usleep(100000);
-	}
-
-      if (context->sn_context)
-	gksu_context_launch_complete (context);
-
-      while (read (parent_pipe[0], buffer, 255) > 0)
-	{
-	  fprintf (stderr, "%s", buffer);
-	  bzero(buffer, 256);
-	}
-
-      /* if the process is still active waitpid() on it */
-      if (pid_exited != pid)
-	waitpid(pid, &status, 0);
-      sudo_reset_xauth (context, xauth, xauth_env);
-
-      if (exit_status)
-      {
-      	if (WIFEXITED(status)) {
-      	  *exit_status = WEXITSTATUS(status);
-	} else if (WIFSIGNALED(status)) {
-	  *exit_status = -1;
-	}
-      }
-
-      if (WEXITSTATUS(status))
-	{
-	  if(cmdline)
-	    {
-	      /* sudo already exec()ed something else, don't report
-	       * exit status errors in that case
-	       */
-	      if (!g_str_has_suffix (cmdline, "sudo"))
-		{
-		  g_free (cmdline);
-		  return FALSE;
-		}
-	      g_free (cmdline);
-	    }
-	  if (error == NULL)
-	    g_set_error (error, gksu_quark,
-			 GKSU_ERROR_CHILDFAILED,
-			 _("sudo terminated with %d status"),
-			 WEXITSTATUS(status));
-	}
-    }
-
-  /* if error is set we have found an error condition */
-  if (error)
-    return FALSE;
-
-  return TRUE;
-}
-
-/**
- * gksu_sudo
- * @command_line: the command line that will be executed as other user
- * @error: a #GError to be set with the error condition, if an error
- * happens
- *
- * This function is a wrapper for gksu_sudo_run_full. It will call it
- * without giving the callback functions, which leads to the standard
- * ones being called. A simple #GksuContext is created to hold the
- * user name and the command.
- *
- * Returns: TRUE if all went well, FALSE if an error happend.
- */
-gboolean
-gksu_sudo (gchar *command_line,
-	   GError **error)
-{
-  GksuContext *context = gksu_context_new ();
-  gboolean retval;
-
-  context->command = g_strdup (command_line);
-  context->user = g_strdup ("root");
-  retval = gksu_sudo_full (context,
-			   NULL, NULL,
-			   NULL, NULL,
-			   error);
-  gksu_context_free (context);
-
-  return retval;
-}
-
-/**
- * gksu_run_full:
- * @context: a #GksuContext
- * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
- * requesting a password is necessary; it may be NULL, in which case
- * the standard password request dialog will be used
- * @ask_pass_data: a #gpointer with user data to be passed to the
- * #GksuAskPasswordFunc
- * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
- * when the command is being run without the need for requesting
- * a password; it will only be called if the display-no-pass-info
- * gconf key is enabled; NULL will have the standard dialog be shown
- * @pass_not_needed_data: a #gpointer with the user data to be passed to the
- * #GksuPasswordNotNeededFunc
- * @error: a #GError object to be filled with the error code or NULL
- *
- * This is a compatibility shim over gksu_run_fuller, which, for
- * compatibility reasons, lacks the 'exit_status' argument.
- *
- * Returns: TRUE if all went fine, FALSE if failed
- */
-
-gboolean
-gksu_run_full (GksuContext *context,
-	       GksuAskPassFunc ask_pass,
-	       gpointer ask_pass_data,
-	       GksuPassNotNeededFunc pass_not_needed,
-	       gpointer pass_not_needed_data,
-	       GError **error)
-{
-  return gksu_run_fuller(context,
-  			 ask_pass, ask_pass_data,
-			 pass_not_needed, pass_not_needed_data,
-			 NULL, error);
-}
-
-/**
- * gksu_run_fuller:
- * @context: a #GksuContext
- * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
- * requesting a password is necessary; it may be NULL, in which case
- * the standard password request dialog will be used
- * @ask_pass_data: a #gpointer with user data to be passed to the
- * #GksuAskPasswordFunc
- * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
- * when the command is being run without the need for requesting
- * a password; it will only be called if the display-no-pass-info
- * gconf key is enabled; NULL will have the standard dialog be shown
- * @pass_not_needed_data: a #gpointer with the user data to be passed to the
- * #GksuPasswordNotNeededFunc
- * @exit_status: an optional pointer to a #gint8 which will be filled with
- * the exit status of the child process
- * @error: a #GError object to be filled with the error code or NULL
- *
- * This function is a wrapper for gksu_sudo_full/gksu_su_full. It will
- * call one of them, depending on the GConf key that defines whether
- * the default behavior for gksu is su or sudo mode. This is the
- * recommended way of using the library functionality.
- *
- * Returns: TRUE if all went fine, FALSE if failed
- */
-gboolean
-gksu_run_fuller (GksuContext *context,
-	         GksuAskPassFunc ask_pass,
-	         gpointer ask_pass_data,
-	         GksuPassNotNeededFunc pass_not_needed,
-	         gpointer pass_not_needed_data,
-		 gint8 *exit_status,
-	         GError **error)
-{
-  GConfClient *gconf_client;
-  gboolean sudo_mode;
-
-  gconf_client = gconf_client_get_default ();
-  sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
-				     NULL);
-  g_object_unref (gconf_client);
-
-  if (sudo_mode)
-    return gksu_sudo_fuller (context, ask_pass, ask_pass_data,
-			     pass_not_needed, pass_not_needed_data,
-			     exit_status, error);
-
-  return gksu_su_fuller (context, ask_pass, ask_pass_data,
-		         pass_not_needed, pass_not_needed_data,
-		         exit_status, error);
-}
-
-/**
- * gksu_run
- * @command_line: the command line that will be executed as other user
- * @error: a #GError to be set with the error condition, if an error
- * happens
- *
- * This function is a wrapper for gksu_sudo/gksu_su. It will call one
- * of them, depending on the GConf key that defines whether the default
- * behavior for gksu is su or sudo mode. This is the recommended way of
- * using the library functionality.
- *
- * Returns: FALSE if all went well, TRUE if an error happend.
- */
-gboolean
-gksu_run (gchar *command_line,
-	  GError **error)
-{
-  GConfClient *gconf_client;
-  gboolean sudo_mode;
-
-  gconf_client = gconf_client_get_default ();
-  sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
-				     NULL);
-  g_object_unref (gconf_client);
-
-  if (sudo_mode)
-    return gksu_sudo (command_line, error);
-
-  return gksu_su (command_line, error);
-}
-
-/**
- * gksu_ask_password_full:
- * @context: a #GksuContext
- * @prompt: a prompt different from Password:
- * @error: a #GError object to be filled with the error code or NULL
- *
- * This function uses the gksu infra-structure to request for a
- * password, but instead of passing it to su or sudo to run a command
- * it simply returns the password.
- *
- * Returns: a newly allocated string with the password;
- */
-gchar*
-gksu_ask_password_full (GksuContext *context, gchar *prompt,
-			GError **error)
-{
-  gchar *ret_value = su_ask_password (context, _(prompt), NULL, error);
-  if (context->sn_context)
-    gksu_context_launch_complete (context);
-  return ret_value;
-}
-
-/**
- * gksu_ask_password
- * @error: a #GError to be set with the error condition, if an error
- * happens
- *
- * This function uses the gksu infra-structure to request for a
- * password, but instead of passing it to su or sudo to run a command
- * it simply returns the password. This is just a convenience wrapper
- * for gksu_ask_password_full.
- *
- * Returns: a newly allocated string with the password;
- */
-gchar*
-gksu_ask_password (GError **error)
-{
-  GksuContext *context = gksu_context_new ();
-  gchar* retval;
-
-  context->user = g_strdup ("root");
-  retval = gksu_ask_password_full (context, NULL, error);
-  gksu_context_free (context);
-
-  return retval;
-}

Copied: libgksu/tags/2.0.9/libgksu/libgksu.c (from rev 846, libgksu/trunk/libgksu/libgksu.c)
===================================================================
--- libgksu/tags/2.0.9/libgksu/libgksu.c	                        (rev 0)
+++ libgksu/tags/2.0.9/libgksu/libgksu.c	2009-03-04 18:55:14 UTC (rev 848)
@@ -0,0 +1,3087 @@
+/*
+ * Gksu -- a library providing access to su functionality
+ * Copyright (C) 2004-2009 Gustavo Noronha Silva
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <pty.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <errno.h>
+
+#include <glibtop.h>
+#include <glibtop/procstate.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#define SN_API_NOT_YET_FROZEN
+#include <libsn/sn.h>
+
+#include <gtk/gtk.h>
+#include <locale.h>
+
+#include <gconf/gconf-client.h>
+#include <gnome-keyring.h>
+
+#include "defines.h"
+#include "../config.h"
+
+#include "libgksu.h"
+#include "../libgksuui/gksuui-dialog.h"
+
+static void
+gksu_context_launch_complete (GksuContext *context);
+
+GType
+gksu_error_get_type (void)
+{
+  static GType etype = 0;
+  if (etype == 0) {
+    static const GEnumValue values[] = {
+      { GKSU_ERROR_HELPER, "GKSU_ERROR_HELPER", "helper" },
+      { GKSU_ERROR_NOCOMMAND, "GKSU_ERROR_NOCOMMAND", "nocommand" },
+      { GKSU_ERROR_NOPASSWORD, "GKSU_ERROR_NOPASSWORD", "nopassword" },
+      { GKSU_ERROR_FORK, "GKSU_ERROR_FORK", "fork" },
+      { GKSU_ERROR_EXEC, "GKSU_ERROR_EXEC", "exec" },
+      { GKSU_ERROR_PIPE, "GKSU_ERROR_PIPE", "pipe" },
+      { GKSU_ERROR_PIPEREAD, "GKSU_ERROR_PIPEREAD", "piperead" },
+      { GKSU_ERROR_WRONGPASS, "GKSU_ERROR_WRONGPASS", "wrongpass" },
+      { GKSU_ERROR_CHILDFAILED, "GKSU_ERROR_CHILDFAILED", "childfailed" },
+      { GKSU_ERROR_CANCELED, "GKSU_ERROR_CANCELED", "canceled" },
+      { GKSU_ERROR_WRONGAUTOPASS, "GKSU_ERROR_WRONGAUTOPASS", "wrongautopass" },
+      { 0, NULL, NULL }
+    };
+    etype = g_enum_register_static ("GksuError", values);
+  }
+  return etype;
+}
+
+static pid_t
+test_lock(const char* fname)
+{
+   int FD = open(fname, 0);
+   if(FD < 0) {
+      if(errno == ENOENT) {
+	 // File does not exist
+	 return 0;
+      } else {
+	 perror("open");
+	 return(-1);
+      }
+   }
+   struct flock fl;
+   fl.l_type = F_WRLCK;
+   fl.l_whence = SEEK_SET;
+   fl.l_start = 0;
+   fl.l_len = 0;
+   if (fcntl(FD, F_GETLK, &fl) < 0) {
+      g_critical("fcntl error");
+      close(FD);
+      return(-1);
+   }
+   close(FD);
+   // lock is available
+   if(fl.l_type == F_UNLCK)
+      return(0);
+   // file is locked by another process
+   return (fl.l_pid);
+}
+
+static int
+get_lock(const char *File)
+{
+   int FD = open(File,O_RDWR | O_CREAT | O_TRUNC,0640);
+   if (FD < 0)
+   {
+      // Read only .. cant have locking problems there.
+      if (errno == EROFS)
+      {
+	 g_warning(_("Not using locking for read only lock file %s"),File);
+	 return dup(0);       // Need something for the caller to close
+      }
+
+      // Feh.. We do this to distinguish the lock vs open case..
+      errno = EPERM;
+      return -1;
+   }
+   fcntl(FD,F_SETFD, FD_CLOEXEC);
+
+   // Aquire a write lock
+   struct flock fl;
+   fl.l_type = F_WRLCK;
+   fl.l_whence = SEEK_SET;
+   fl.l_start = 0;
+   fl.l_len = 0;
+   if (fcntl(FD,F_SETLK,&fl) == -1)
+   {
+      if (errno == ENOLCK)
+      {
+	 g_warning(_("Not using locking for nfs mounted lock file %s"), File);
+	 unlink(File);
+	 close(FD);
+	 return dup(0);       // Need something for the caller to close
+      }
+
+      int Tmp = errno;
+      close(FD);
+      errno = Tmp;
+      return -1;
+   }
+
+   return FD;
+}
+
+/*
+ * code 'stolen' from gnome-session's logout.c
+ *
+ * Written by Owen Taylor <otaylor at redhat.com>
+ * Copyright (C) Red Hat
+ */
+typedef struct {
+  GdkScreen    *screen;
+  int           monitor;
+  GdkRectangle  area;
+  int           rowstride;
+  GdkWindow    *root_window;
+  GdkWindow    *draw_window;
+  GdkPixbuf    *start_pb, *end_pb, *frame;
+  guchar       *start_p, *end_p, *frame_p;
+  GTimeVal      start_time;
+  GdkGC        *gc;
+} FadeoutData;
+
+FadeoutData *fade_data = NULL;
+static GList *fadeout_windows = NULL;
+
+#define FADE_DURATION 500.0
+
+int
+gsm_screen_get_width (GdkScreen *screen,
+		      int        monitor)
+{
+	GdkRectangle geometry;
+
+	gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+
+	return geometry.width;
+}
+
+int
+gsm_screen_get_height (GdkScreen *screen,
+		       int        monitor)
+{
+	GdkRectangle geometry;
+
+	gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+
+	return geometry.height;
+}
+
+int
+gsm_screen_get_x (GdkScreen *screen,
+		  int        monitor)
+{
+	GdkRectangle geometry;
+
+	gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+
+	return geometry.x;
+}
+
+int
+gsm_screen_get_y (GdkScreen *screen,
+		  int        monitor)
+{
+	GdkRectangle geometry;
+
+	gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+
+	return geometry.y;
+}
+
+static void
+get_current_frame (FadeoutData *fadeout,
+		   double    sat)
+{
+  guchar *sp, *ep, *fp;
+  int i, j, width, offset;
+
+  width = fadeout->area.width * 3;
+  offset = 0;
+
+  for (i = 0; i < fadeout->area.height; i++)
+    {
+      sp = fadeout->start_p + offset;
+      ep = fadeout->end_p   + offset;
+      fp = fadeout->frame_p + offset;
+
+      for (j = 0; j < width; j += 3)
+	{
+	  guchar r = abs (*(sp++) - ep[0]);
+	  guchar g = abs (*(sp++) - ep[1]);
+	  guchar b = abs (*(sp++) - ep[2]);
+
+	  *(fp++) = *(ep++) + r * sat;
+	  *(fp++) = *(ep++) + g * sat;
+	  *(fp++) = *(ep++) + b * sat;
+	}
+
+      offset += fadeout->rowstride;
+    }
+}
+
+static void
+darken_pixbuf (GdkPixbuf *pb)
+{
+  int width, height, rowstride;
+  int i, j;
+  guchar *p, *pixels;
+
+  width     = gdk_pixbuf_get_width (pb) * 3;
+  height    = gdk_pixbuf_get_height (pb);
+  rowstride = gdk_pixbuf_get_rowstride (pb);
+  pixels    = gdk_pixbuf_get_pixels (pb);
+
+  for (i = 0; i < height; i++)
+    {
+      p = pixels + (i * rowstride);
+      for (j = 0; j < width; j++)
+	p [j] >>= 1;
+    }
+}
+
+static gboolean
+fadeout_callback (FadeoutData *fadeout)
+{
+  GTimeVal current_time;
+  double elapsed, percent;
+
+  g_get_current_time (&current_time);
+  elapsed = ((((double)current_time.tv_sec - fadeout->start_time.tv_sec) * G_USEC_PER_SEC +
+	      (current_time.tv_usec - fadeout->start_time.tv_usec))) / 1000.0;
+
+  if (elapsed < 0)
+    {
+      g_warning ("System clock seemed to go backwards?");
+      elapsed = G_MAXDOUBLE;
+    }
+
+  if (elapsed > FADE_DURATION)
+    {
+      gdk_draw_pixbuf (fadeout->draw_window,
+		       fadeout->gc,
+		       fadeout->end_pb,
+		       0, 0,
+		       0, 0,
+		       fadeout->area.width,
+		       fadeout->area.height,
+		       GDK_RGB_DITHER_NONE,
+		       0, 0);
+
+      return FALSE;
+    }
+
+  percent = elapsed / FADE_DURATION;
+
+  get_current_frame (fadeout, 1.0 - percent);
+  gdk_draw_pixbuf (fadeout->draw_window,
+		   fadeout->gc,
+		   fadeout->frame,
+		   0, 0,
+		   0, 0,
+		   fadeout->area.width,
+		   fadeout->area.height,
+		   GDK_RGB_DITHER_NONE,
+		   0, 0);
+
+  gdk_flush ();
+
+  return TRUE;
+}
+
+static void
+hide_fadeout_windows (void)
+{
+  GList *l;
+
+  for (l = fadeout_windows; l; l = l->next)
+    {
+      gdk_window_hide (GDK_WINDOW (l->data));
+      g_object_unref (l->data);
+    }
+
+  g_list_free (fadeout_windows);
+  fadeout_windows = NULL;
+}
+
+static gboolean
+fadein_callback (FadeoutData *fadeout)
+{
+  GTimeVal current_time;
+  double elapsed, percent;
+
+  g_get_current_time (&current_time);
+  elapsed = ((((double)current_time.tv_sec - fadeout->start_time.tv_sec) * G_USEC_PER_SEC +
+	      (current_time.tv_usec - fadeout->start_time.tv_usec))) / 1000.0;
+
+  if (elapsed < 0)
+    {
+      g_warning ("System clock seemed to go backwards?");
+      elapsed = G_MAXDOUBLE;
+    }
+
+  if (elapsed > FADE_DURATION)
+    {
+      gdk_draw_pixbuf (fadeout->draw_window,
+		       fadeout->gc,
+		       fadeout->end_pb,
+		       0, 0,
+		       0, 0,
+		       fadeout->area.width,
+		       fadeout->area.height,
+		       GDK_RGB_DITHER_NONE,
+		       0, 0);
+
+      g_object_unref (fadeout->gc);
+      g_object_unref (fadeout->start_pb);
+      g_object_unref (fadeout->end_pb);
+      g_object_unref (fadeout->frame);
+
+      g_free (fadeout);
+
+      hide_fadeout_windows ();
+
+      return FALSE;
+    }
+
+  percent = elapsed / FADE_DURATION;
+
+  get_current_frame (fadeout, percent);
+  gdk_draw_pixbuf (fadeout->draw_window,
+		   fadeout->gc,
+		   fadeout->frame,
+		   0, 0,
+		   0, 0,
+		   fadeout->area.width,
+		   fadeout->area.height,
+		   GDK_RGB_DITHER_NONE,
+		   0, 0);
+
+  gdk_flush ();
+
+  return TRUE;
+}
+
+static void
+fadeout_screen (GdkScreen *screen,
+		int        monitor)
+{
+  GdkWindowAttr attr;
+  int attr_mask;
+  GdkGCValues values;
+  FadeoutData *fadeout;
+
+  fadeout = g_new (FadeoutData, 1);
+
+  fadeout->screen = screen;
+  fadeout->monitor = monitor;
+
+  fadeout->area.x = gsm_screen_get_x (screen, monitor);
+  fadeout->area.y = gsm_screen_get_y (screen, monitor);
+  fadeout->area.width = gsm_screen_get_width (screen, monitor);
+  fadeout->area.height = gsm_screen_get_height (screen, monitor);
+
+  fadeout->root_window = gdk_screen_get_root_window (screen);
+  attr.window_type = GDK_WINDOW_CHILD;
+  attr.x = fadeout->area.x;
+  attr.y = fadeout->area.y;
+  attr.width = fadeout->area.width;
+  attr.height = fadeout->area.height;
+  attr.wclass = GDK_INPUT_OUTPUT;
+  attr.visual = gdk_screen_get_system_visual (fadeout->screen);
+  attr.colormap = gdk_screen_get_default_colormap (fadeout->screen);
+  attr.override_redirect = TRUE;
+  attr_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_NOREDIR;
+
+  fadeout->draw_window = gdk_window_new (fadeout->root_window, &attr, attr_mask);
+  fadeout_windows = g_list_prepend (fadeout_windows, fadeout->draw_window);
+
+  fadeout->start_pb = gdk_pixbuf_get_from_drawable (NULL,
+						    fadeout->root_window,
+						    NULL,
+						    fadeout->area.x,
+						    fadeout->area.y,
+						    0, 0,
+						    fadeout->area.width,
+						    fadeout->area.height);
+
+  fadeout->end_pb = gdk_pixbuf_copy (fadeout->start_pb);
+  darken_pixbuf (fadeout->end_pb);
+
+  fadeout->frame = gdk_pixbuf_copy (fadeout->start_pb);
+  fadeout->rowstride = gdk_pixbuf_get_rowstride (fadeout->start_pb);
+
+  fadeout->start_p = gdk_pixbuf_get_pixels (fadeout->start_pb);
+  fadeout->end_p   = gdk_pixbuf_get_pixels (fadeout->end_pb);
+  fadeout->frame_p = gdk_pixbuf_get_pixels (fadeout->frame);
+
+  values.subwindow_mode = GDK_INCLUDE_INFERIORS;
+
+  fadeout->gc = gdk_gc_new_with_values (fadeout->root_window, &values, GDK_GC_SUBWINDOW);
+
+  gdk_window_set_back_pixmap (fadeout->draw_window, NULL, FALSE);
+  gdk_window_show (fadeout->draw_window);
+  gdk_draw_pixbuf (fadeout->draw_window,
+		   fadeout->gc,
+		   fadeout->frame,
+		   0, 0,
+		   0, 0,
+		   fadeout->area.width,
+		   fadeout->area.height,
+		   GDK_RGB_DITHER_NONE,
+		   0, 0);
+
+  g_get_current_time (&fadeout->start_time);
+  g_idle_add ((GSourceFunc) fadeout_callback, fadeout);
+
+  fade_data = fadeout;
+}
+
+/* End of 'stolen' code */
+
+#define GRAB_TRIES	16
+#define GRAB_WAIT	250 /* milliseconds */
+
+typedef enum
+  {
+    FAILED_GRAB_MOUSE,
+    FAILED_GRAB_KEYBOARD
+  } FailedGrabWhat;
+
+void
+report_failed_grab (FailedGrabWhat what)
+{
+  GtkWidget *dialog;
+
+  dialog = g_object_new (GTK_TYPE_MESSAGE_DIALOG,
+			 "message-type", GTK_MESSAGE_WARNING,
+			 "buttons", GTK_BUTTONS_CLOSE,
+			 NULL);
+
+  switch (what)
+    {
+    case FAILED_GRAB_MOUSE:
+      gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG(dialog),
+				     _("<b><big>Could not grab your mouse.</big></b>"
+				       "\n\n"
+				       "A malicious client may be eavesdropping "
+				       "on your session or you may have just clicked "
+				       "a menu or some application just decided to get "
+				       "focus."
+				       "\n\n"
+				       "Try again."));
+
+      break;
+    case FAILED_GRAB_KEYBOARD:
+      gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG(dialog),
+				     _("<b><big>Could not grab your keyboard.</big></b>"
+				       "\n\n"
+				       "A malicious client may be eavesdropping "
+				       "on your session or you may have just clicked "
+				       "a menu or some application just decided to get "
+				       "focus."
+				       "\n\n"
+				       "Try again."));
+      break;
+    }
+
+  gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
+  gtk_dialog_run (GTK_DIALOG(dialog));
+  gtk_widget_destroy (dialog);
+
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+}
+
+int
+grab_keyboard_and_mouse (GtkWidget *dialog)
+{
+  GdkGrabStatus status;
+  gint grab_tries = 0;
+  gint lock = -1;
+  pid_t pid;
+
+  gchar *fname = g_strdup (getenv ("GKSU_LOCK_FILE"));
+  if (fname == NULL)
+    fname = g_strdup_printf ("%s/.gksu.lock", getenv ("HOME"));
+
+  pid = test_lock (fname);
+
+  if (pid != 0)
+    {
+      g_warning ("Lock taken by pid: %i. Exiting.", pid);
+      exit (0);
+    }
+
+  lock = get_lock(fname);
+  if( lock < 0)
+    g_warning ("Unable to create lock file.");
+  g_free (fname);
+
+  gdk_threads_enter ();
+  fadeout_screen (gdk_screen_get_default (), 0);
+  gtk_widget_show_all (dialog);
+
+  /* reset cursor */
+  gdk_window_set_cursor(dialog->window, gdk_cursor_new(GDK_LEFT_PTR));
+
+  for(;;)
+    {
+      status = gdk_pointer_grab ((GTK_WIDGET(dialog))->window, TRUE, 0, NULL,
+				 NULL, GDK_CURRENT_TIME);
+      if (status == GDK_GRAB_SUCCESS)
+	break;
+      usleep (GRAB_WAIT * 1000);
+      if (++grab_tries > GRAB_TRIES)
+	{
+	  gtk_widget_hide (dialog);
+	  g_get_current_time (&fade_data->start_time);
+	  while (fadein_callback (fade_data) != FALSE);
+	  report_failed_grab (FAILED_GRAB_MOUSE);
+	  exit (1);
+	  break;
+	}
+    }
+
+  for(;;)
+    {
+      status = gdk_keyboard_grab ((GTK_WIDGET(dialog))->window,
+				  FALSE, GDK_CURRENT_TIME);
+      if (status == GDK_GRAB_SUCCESS)
+	break;
+
+      usleep(GRAB_WAIT * 1000);
+
+      if (++grab_tries > GRAB_TRIES)
+	{
+	  gtk_widget_hide (dialog);
+	  g_get_current_time (&fade_data->start_time);
+	  while (fadein_callback (fade_data) != FALSE);
+	  report_failed_grab (FAILED_GRAB_KEYBOARD);
+	  exit (1);
+	  break;
+	}
+    }
+
+  /* we "raise" the window because there is a race here for
+   * focus-follow-mouse and auto-raise WMs that may put the window
+   * in the background and confuse users
+   */
+  gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
+
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  return lock;
+}
+
+void
+ungrab_keyboard_and_mouse (int lock)
+{
+  /* Ungrab */
+  gdk_pointer_ungrab(GDK_CURRENT_TIME);
+  gdk_keyboard_ungrab(GDK_CURRENT_TIME);
+  gdk_flush();
+
+  g_get_current_time (&fade_data->start_time);
+  while (fadein_callback (fade_data) != FALSE);
+  gdk_threads_leave();
+
+  close(lock);
+}
+
+static gchar*
+get_gnome_keyring_password (GksuContext *context)
+{
+  GnomeKeyringAttributeList *attributes;
+  GnomeKeyringAttribute attribute;
+  GnomeKeyringResult result;
+  GList *list;
+
+  attributes = gnome_keyring_attribute_list_new ();
+
+  attribute.name = g_strdup ("user");
+  attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+  attribute.value.string = g_strdup (gksu_context_get_user (context));
+  g_array_append_val (attributes, attribute);
+
+  attribute.name = g_strdup ("type");
+  attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+  attribute.value.string = g_strdup ("local");
+  g_array_append_val (attributes, attribute);
+
+  attribute.name = g_strdup ("creator");
+  attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+  attribute.value.string = g_strdup ("gksu");
+  g_array_append_val (attributes, attribute);
+
+  list = g_list_alloc();
+
+  result = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
+					  attributes,
+					  &list);
+  gnome_keyring_attribute_list_free (attributes);
+  if (
+      (result == GNOME_KEYRING_RESULT_OK) &&
+      (g_list_length(list) >= 1)
+      )
+    {
+      GnomeKeyringFound *found = list->data;
+      gint password_length = strlen (found->secret);
+      gchar *password;
+
+      password = g_locale_from_utf8 (found->secret,
+				     password_length,
+				     NULL, NULL, NULL);
+      password_length = strlen (password);
+
+      if (password[password_length-1] == '\n')
+	password[password_length-1] = '\0';
+      return password;
+    }
+
+  return NULL;
+}
+
+static void
+keyring_create_item_cb (GnomeKeyringResult result,
+                        guint32 id, gpointer keyring_loop)
+{
+  g_main_loop_quit (keyring_loop);
+}
+
+static void
+set_gnome_keyring_password (GksuContext *context, gchar *password)
+{
+  GConfClient *gconf_client;
+  gboolean save_to_keyring;
+
+  gconf_client = context->gconf_client;
+  save_to_keyring = gconf_client_get_bool (gconf_client, BASE_PATH"save-to-keyring", NULL);
+
+  if (password && save_to_keyring)
+    {
+      static GMainLoop *keyring_loop = NULL;
+      GnomeKeyringAttributeList *attributes;
+      GnomeKeyringAttribute attribute;
+      GnomeKeyringResult result;
+
+      gchar *keyring_name;
+      gchar *key_name;
+
+      attributes = gnome_keyring_attribute_list_new ();
+
+      attribute.name = g_strdup ("user");
+      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+      attribute.value.string = g_strdup (gksu_context_get_user (context));
+      g_array_append_val (attributes, attribute);
+
+      attribute.name = g_strdup ("type");
+      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+      attribute.value.string = g_strdup ("local");
+      g_array_append_val (attributes, attribute);
+
+      attribute.name = g_strdup ("creator");
+      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+      attribute.value.string = g_strdup ("gksu");
+      g_array_append_val (attributes, attribute);
+
+      key_name = g_strdup_printf ("Local password for user %s",
+				  gksu_context_get_user (context));
+
+      keyring_loop = g_main_loop_new (NULL, FALSE);
+
+      keyring_name = gconf_client_get_string (gconf_client, BASE_PATH"save-keyring", NULL);
+      if (keyring_name == NULL)
+	keyring_name = g_strdup ("session");
+
+      /* make sure the keyring exists; if an error occurs, use
+         the session keyring */
+      result = gnome_keyring_create_sync(keyring_name, NULL);
+      if ((result != GNOME_KEYRING_RESULT_OK) &&
+	  (result != GNOME_KEYRING_RESULT_ALREADY_EXISTS))
+	keyring_name = g_strdup ("session");
+
+      gnome_keyring_item_create (keyring_name,
+				 GNOME_KEYRING_ITEM_GENERIC_SECRET,
+				 key_name,
+				 attributes,
+				 password,
+				 TRUE,
+				 keyring_create_item_cb,
+				 keyring_loop, NULL);
+      gnome_keyring_attribute_list_free (attributes);
+      g_free (keyring_name);
+      g_main_loop_run (keyring_loop);
+    }
+}
+
+static void
+unset_gnome_keyring_password (GksuContext *context)
+{
+  GConfClient *gconf_client;
+  gboolean save_to_keyring;
+
+  GnomeKeyringAttributeList *attributes;
+  GnomeKeyringAttribute attribute;
+  GnomeKeyringResult result;
+  GList *list;
+
+  gconf_client = context->gconf_client;
+  save_to_keyring = gconf_client_get_bool (gconf_client, BASE_PATH"save-to-keyring", NULL);
+
+  if (save_to_keyring)
+    {
+      attributes = gnome_keyring_attribute_list_new ();
+
+      attribute.name = g_strdup ("user");
+      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+      attribute.value.string = g_strdup (gksu_context_get_user (context));
+      g_array_append_val (attributes, attribute);
+
+      attribute.name = g_strdup ("type");
+      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+      attribute.value.string = g_strdup ("local");
+      g_array_append_val (attributes, attribute);
+
+      attribute.name = g_strdup ("creator");
+      attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
+      attribute.value.string = g_strdup ("gksu");
+      g_array_append_val (attributes, attribute);
+
+      list = g_list_alloc();
+
+      result = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET,
+					      attributes,
+					      &list);
+      gnome_keyring_attribute_list_free (attributes);
+      if (
+	  (result == GNOME_KEYRING_RESULT_OK) &&
+	  (g_list_length(list) == 1)
+	  )
+	{
+	  GnomeKeyringFound *found = list->data;
+
+	  gnome_keyring_item_delete_sync (found->keyring,
+					  found->item_id);
+	}
+    }
+}
+
+void
+get_configuration_options (GksuContext *context)
+{
+  GConfClient *gconf_client = context->gconf_client;
+  gboolean force_grab;
+
+  context->grab = !gconf_client_get_bool (gconf_client, BASE_PATH "disable-grab",
+					  NULL);
+  force_grab = gconf_client_get_bool (gconf_client, BASE_PATH "force-grab",
+				      NULL);
+  if (force_grab)
+    context->grab = TRUE;
+
+  context->sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
+					      NULL);
+}
+
+/**
+ * su_ask_password:
+ * @context: a #GksuContext
+ * @prompt: the prompt that should be used instead of "Password: "
+ * @data: data that is passed by gksu_*_full
+ * @error: a pointer to pointer #GError that will be filled with
+ * data if an error happens.
+ *
+ * This is a convenience function to create a #GksuuiDialog and
+ * request the password.
+ *
+ * Returns: a newly allocated gchar containing the password
+ * or NULL if an error happens or the user cancels the action
+ */
+static gchar*
+su_ask_password (GksuContext *context, gchar *prompt,
+		 gpointer data, GError **error)
+{
+  GtkWidget *dialog = NULL;
+  gchar *msg;
+  gchar *password = NULL, *tmp = NULL;
+  int retvalue = 0;
+  int lock = 0;
+  GQuark gksu_quark;
+
+  gksu_quark = g_quark_from_string (PACKAGE);
+
+  if (context->grab)
+    dialog = g_object_new (GKSUUI_TYPE_DIALOG,
+			   "type", GTK_WINDOW_POPUP,
+			   "sudo-mode", context->sudo_mode,
+			   NULL);
+  else
+    dialog = gksuui_dialog_new (context->sudo_mode);
+
+  if (prompt)
+    gksuui_dialog_set_prompt (GKSUUI_DIALOG(dialog), _(prompt));
+
+  if (context->message)
+    gksuui_dialog_set_message (GKSUUI_DIALOG(dialog), context->message);
+  else
+    {
+      gchar *command = NULL;
+      if (context->description)
+	command = context->description;
+      else
+	command = context->command;
+
+      if (context->sudo_mode)
+	{
+	  if (!strcmp(context->user, "root"))
+	    msg = g_strdup_printf (_("<b><big>Enter your password to perform"
+				     " administrative tasks</big></b>\n\n"
+				     "The application '%s' lets you "
+				     "modify essential parts of your "
+				     "system."),
+				   command);
+	  else
+	    msg = g_strdup_printf (_("<b><big>Enter your password to run "
+				     "the application '%s' as user %s"
+				     "</big></b>"),
+				   command, context->user);
+	}
+      else
+	{
+        if (strcmp(gksu_context_get_user (context), "root") == 0)
+          msg = g_strdup_printf (_("<b><big>Enter the administrative password"
+                                   "</big></b>\n\n"
+                                   "The application '%s' lets you "
+                                   "modify essential parts of your "
+                                   "system."),
+				   command);
+        else
+          msg = g_strdup_printf (_("<b><big>Enter the password of %s to run "
+                                   "the application '%s'"
+                                   "</big></b>"),
+				   context->user, command);
+      }
+
+      gksuui_dialog_set_message (GKSUUI_DIALOG(dialog), msg);
+      g_free (msg);
+    }
+
+  if (context->alert)
+    gksuui_dialog_set_alert (GKSUUI_DIALOG(dialog), context->alert);
+
+  if (context->grab)
+    lock = grab_keyboard_and_mouse (dialog);
+  retvalue = gtk_dialog_run (GTK_DIALOG(dialog));
+  gtk_widget_hide (dialog);
+  if (context->grab)
+    ungrab_keyboard_and_mouse (lock);
+
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  if (retvalue != GTK_RESPONSE_OK)
+    {
+      switch (retvalue)
+	{
+	case GTK_RESPONSE_CANCEL:
+	case GTK_RESPONSE_DELETE_EVENT:
+	  g_set_error (error, gksu_quark,
+		       GKSU_ERROR_CANCELED,
+		       _("Password prompt canceled."));
+	  if (context->sn_context)
+	    gksu_context_launch_complete (context);
+	}
+
+      gtk_widget_destroy (dialog);
+      while (gtk_events_pending ())
+	gtk_main_iteration ();
+
+      return NULL;
+    }
+
+  tmp = gksuui_dialog_get_password (GKSUUI_DIALOG(dialog));
+  password = g_locale_from_utf8 (tmp, strlen (tmp), NULL, NULL, NULL);
+  g_free (tmp);
+
+  gtk_widget_destroy (dialog);
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+
+  return password;
+}
+
+static void
+cb_toggled_cb (GtkWidget *button, gpointer data)
+{
+  GConfClient *gconf_client;
+  gchar *key;
+  gboolean toggled;
+  gchar *key_name;
+
+  g_return_if_fail (data != NULL);
+
+  key_name = (gchar*)data;
+
+  gconf_client = gconf_client_get_default ();
+  toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button));
+
+  key = g_strdup_printf (BASE_PATH "%s", key_name);
+
+  if (!strcmp (key_name, "display-no-pass-info"))
+    {
+      /* the meaning of the key is the exact opposite of the meaning
+	 of the answer - when the check button is checked the key must
+	 be off
+      */
+      gconf_client_set_bool (gconf_client, key, !toggled, NULL);
+    }
+  else
+    gconf_client_set_bool (gconf_client, key, toggled, NULL);
+
+  g_object_unref (gconf_client);
+
+  g_free (key);
+}
+
+void
+no_pass (GksuContext *context, gpointer data)
+{
+  GtkWidget *dialog;
+  GtkWidget *alignment;
+  GtkWidget *check_button;
+
+  gchar *command = NULL;
+
+  if (context->description)
+    command = context->description;
+  else
+    command = context->command;
+
+  dialog = gtk_message_dialog_new_with_markup (NULL, 0,
+					       GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
+					       _("<b><big>Granted permissions without asking "
+						 "for password</big></b>"
+						 "\n\n"
+						 "The '%s' program was started with "
+						 "the privileges of the %s user without "
+						 "the need to ask for a password, due to "
+						 "your system's authentication mechanism "
+						 "setup."
+						 "\n\n"
+						 "It is possible that you are being allowed "
+						 "to run specific programs as user %s "
+						 "without the need for a password, or that "
+						 "the password is cached."
+						 "\n\n"
+						 "This is not a problem report; it's "
+						 "simply a notification to make sure "
+						 "you are aware of this."),
+					       command,
+					       context->user,
+					       context->user);
+
+  alignment = gtk_alignment_new (0.5, 0.5, 0.6, 1);
+  gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), alignment, TRUE, TRUE, 2);
+
+  check_button = gtk_check_button_new_with_mnemonic (_("Do _not display this message again"));
+  g_signal_connect (G_OBJECT(check_button), "toggled",
+		    G_CALLBACK(cb_toggled_cb), "display-no-pass-info");
+  gtk_container_add (GTK_CONTAINER(alignment), check_button);
+
+  gtk_widget_show_all (dialog);
+  gtk_dialog_run (GTK_DIALOG(dialog));
+  gtk_widget_destroy (GTK_WIDGET(dialog));
+
+  while (gtk_events_pending ())
+    gtk_main_iteration ();
+}
+
+static void
+gksu_prompt_grab (GksuContext *context)
+{
+  GtkWidget *d;
+
+  d = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_QUESTION,
+					  GTK_BUTTONS_YES_NO,
+					  _("<b>Would you like your screen to be \"grabbed\"\n"
+					    "while you enter the password?</b>"
+					    "\n\n"
+					    "This means all applications will be paused to avoid\n"
+					    "the eavesdropping of your password by a a malicious\n"
+					    "application while you type it."));
+
+  if (gtk_dialog_run (GTK_DIALOG(d)) == GTK_RESPONSE_NO)
+    context->grab = FALSE;
+  else
+    context->grab = TRUE;
+
+  gtk_widget_destroy (d);
+}
+
+static void
+nullify_password (gchar *pass)
+{
+  if (pass)
+    {
+      memset(pass, 0, strlen(pass));
+      g_free (pass);
+    }
+  pass = NULL;
+}
+
+static gchar *
+get_process_name (pid_t pid)
+{
+  static gboolean init;
+  glibtop_proc_state buf;
+
+  if (!init) {
+    glibtop_init();
+    init = TRUE;
+  }
+
+  glibtop_get_proc_state (&buf, pid);
+  return strdup(buf.cmd);
+}
+
+static gchar *
+get_xauth_token (GksuContext *context, gchar *display)
+{
+  gchar *xauth_bin = NULL;
+  FILE *xauth_output;
+  gchar *tmp = NULL;
+  gchar *xauth = g_new0 (gchar, 256);
+
+  /* find out where the xauth binary is located */
+  if (g_file_test ("/usr/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
+    xauth_bin = "/usr/bin/xauth";
+  else if (g_file_test ("/usr/X11R6/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
+    xauth_bin = "/usr/X11R6/bin/xauth";
+  else
+    {
+      fprintf (stderr,
+	       "Failed to obtain xauth key: xauth binary not found "
+	       "at usual locations");
+
+      return NULL;
+    }
+
+  /* get the authorization token */
+  tmp = g_strdup_printf ("%s list %s | "
+			 "head -1 | awk '{ print $3 }'",
+			 xauth_bin,
+			 display);
+  if ((xauth_output = popen (tmp, "r")) == NULL)
+    {
+      fprintf (stderr,
+	       "Failed to obtain xauth key: %s",
+	       strerror(errno));
+      return NULL;
+    }
+  fread (xauth, sizeof(char), 255, xauth_output);
+  pclose (xauth_output);
+  g_free (tmp);
+
+  if (context->debug)
+    {
+      fprintf(stderr,
+	      "xauth: -%s-\n"
+	      "display: -%s-\n",
+	      xauth, display);
+    }
+
+  return xauth;
+}
+
+/**
+ * prepare_xauth:
+ *
+ * Sets up the variables with values for the $DISPLAY
+ * environment variable and xauth-related stuff. Also
+ * creates a temporary directory to hold a .Xauthority
+ *
+ * Returns: TRUE if it suceeds, FALSE if it fails.
+ */
+static int
+prepare_xauth (GksuContext *context)
+{
+  gchar *display = NULL;
+  gchar *xauth = NULL;
+
+  display = g_strdup (getenv ("DISPLAY"));
+  xauth = get_xauth_token (context, display);
+  if (xauth == NULL)
+    {
+      g_free (display);
+      return FALSE;
+    }
+
+  /* If xauth is the empty string, then try striping the
+   * hostname part of the DISPLAY string for getting the
+   * auth token; this is needed for ssh-forwarded usage
+   */
+  if (!strcmp ("", xauth))
+    {
+      gchar *cut_display = NULL;
+
+      g_free (xauth);
+      cut_display = g_strdup (g_strrstr (display, ":"));
+      xauth = get_xauth_token (context, cut_display);
+
+      g_free (display);
+      display = cut_display;
+    }
+
+  context->xauth = xauth;
+  context->display = display;
+
+  if (context->debug)
+    {
+      fprintf(stderr,
+	      "final xauth: -%s-\n"
+	      "final display: -%s-\n",
+	      context->xauth, context->display);
+    }
+
+  return TRUE;
+}
+
+/* Write all of buf, even if write(2) is interrupted. */
+static ssize_t
+full_write (int d, const char *buf, size_t nbytes)
+{
+  ssize_t r, w = 0;
+
+  /* Loop until nbytes of buf have been written. */
+  while (w < nbytes) {
+    /* Keep trying until write succeeds without interruption. */
+    do {
+      r = write(d, buf + w, nbytes - w);
+    } while (r < 0 && errno == EINTR);
+
+    if (r < 0) {
+      return -1;
+    }
+
+    w += r;
+  }
+
+  return w;
+}
+
+static gboolean
+copy (const char *fn, const char *dir)
+{
+  int in, out;
+  int r;
+  char *newfn;
+  char buf[BUFSIZ] = "";
+
+  newfn = g_strdup_printf("%s/.Xauthority", dir);
+
+  out = open(newfn, O_WRONLY | O_CREAT | O_EXCL, 0600);
+  if (out == -1)
+    {
+      if (errno == EEXIST)
+	fprintf (stderr,
+		 "Impossible to create the .Xauthority file: a file "
+		 "already exists. This might be a security issue; "
+		 "please investigate.");
+      else
+	fprintf (stderr,
+		 "Error copying '%s' to '%s': %s",
+		 fn, dir, strerror(errno));
+
+      return FALSE;
+    }
+
+  in = open(fn, O_RDONLY);
+  if (in == -1)
+    {
+      fprintf (stderr,
+	       "Error copying '%s' to '%s': %s",
+	       fn, dir, strerror(errno));
+      return FALSE;
+    }
+
+  while ((r = read(in, buf, BUFSIZ)) > 0)
+    {
+      if (full_write(out, buf, r) == -1)
+	{
+	  fprintf (stderr,
+		   "Error copying '%s' to '%s': %s",
+		   fn, dir, strerror(errno));
+	  return FALSE;
+	}
+    }
+
+  if (r == -1)
+    {
+      fprintf (stderr,
+	       "Error copying '%s' to '%s': %s",
+	       fn, dir, strerror(errno));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static gboolean
+sudo_prepare_xauth (GksuContext *context)
+{
+  gchar template[] = "/tmp/" PACKAGE "-XXXXXX";
+  gboolean error_copying = FALSE;
+  gchar *xauth = NULL;
+
+  context->dir = g_strdup (mkdtemp(template));
+  if (!context->dir)
+    {
+      fprintf (stderr, strerror(errno));
+      return FALSE;
+    }
+
+  xauth = g_strdup(g_getenv ("XAUTHORITY"));
+  if (xauth == NULL)
+    xauth = g_strdup_printf ("%s/.Xauthority", g_get_home_dir());
+
+  error_copying = !copy (xauth, context->dir);
+  g_free (xauth);
+
+  if (error_copying)
+    return FALSE;
+
+  return TRUE;
+}
+
+static void
+sudo_reset_xauth (GksuContext *context, gchar *xauth,
+		  gchar *xauth_env)
+{
+  /* reset the env var as it was before or clean it  */
+  if (xauth_env)
+    setenv ("XAUTHORITY", xauth_env, TRUE);
+  else
+    unsetenv ("XAUTHORITY");
+
+  if (context->debug)
+    fprintf (stderr, "xauth: %s\nxauth_env: %s\ndir: %s\n",
+	     xauth, xauth_env, context->dir);
+
+  unlink (xauth);
+  rmdir (context->dir);
+
+  g_free (xauth);
+}
+
+static void
+startup_notification_initialize (GksuContext *context)
+{
+  SnDisplay *sn_display;
+  sn_display = sn_display_new (GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
+			       NULL, NULL);
+  context->sn_context = sn_launcher_context_new (sn_display, gdk_screen_get_number (gdk_display_get_default_screen (gdk_display_get_default ())));
+  sn_launcher_context_set_description (context->sn_context, _("Granting Rights"));
+  sn_launcher_context_set_name (context->sn_context, g_get_prgname ());
+}
+
+/**
+ * gksu_context_new
+ *
+ * This function should be used when creating a new #GksuContext to
+ * pass to gksu_su_full or gksu_sudo_full. The #GksuContext must be
+ * freed with gksu_context_free.
+ *
+ * Returns: a newly allocated #GksuContext
+ */
+GksuContext*
+gksu_context_new ()
+{
+  GksuContext *context;
+
+  context = g_new (GksuContext, 1);
+
+  context->xauth = NULL;
+  context->dir = NULL;
+  context->display = NULL;
+
+  context->gconf_client = gconf_client_get_default ();
+
+  context->sudo_mode = FALSE;
+
+  context->user = g_strdup ("root");
+  context->command = NULL;
+
+  context->login_shell = FALSE;
+  context->keep_env = FALSE;
+
+  context->description = NULL;
+  context->message = NULL;
+  context->alert = NULL;
+  context->grab = TRUE;
+  context->always_ask_password = FALSE;
+
+  context->debug = FALSE;
+
+  context->sn_context = NULL;
+  context->sn_id = NULL;
+  
+  context->ref_count = 1;
+
+  get_configuration_options (context);
+  startup_notification_initialize (context);
+
+  return context;
+}
+
+/**
+ * gksu_context_set_user:
+ * @context: the #GksuContext you want to modify
+ * @username: the target username
+ *
+ * Sets up what user the command will be run as. The default
+ * is root, but you can run the command as any user.
+ *
+ */
+void
+gksu_context_set_user (GksuContext *context, gchar *username)
+{
+  g_assert (username != NULL);
+
+  if (context->user)
+    g_free (context->user);
+  context->user = g_strdup (username);
+}
+
+/**
+ * gksu_context_get_user:
+ * @context: the #GksuContext from which to grab the information
+ *
+ * Gets the user the command will be run as, as set
+ * by gksu_context_set_user.
+ *
+ * Returns: a string with the user or NULL if not set.
+ */
+const gchar*
+gksu_context_get_user (GksuContext *context)
+{
+  return context->user;
+}
+
+/**
+ * gksu_context_set_command:
+ * @context: the #GksuContext you want to modify
+ * @command: the command that shall be ran
+ *
+ * Sets up what command will run with the target user.
+ *
+ */
+void
+gksu_context_set_command (GksuContext *context, gchar *command)
+{
+  g_assert (command != NULL);
+
+  if (context->command)
+    g_free (context->command);
+  context->command = g_strdup (command);
+
+  /* startup notification */
+  sn_launcher_context_set_binary_name (context->sn_context,
+				       command);
+}
+
+/**
+ * gksu_context_get_command:
+ * @context: the #GksuContext from which to grab the information
+ *
+ * Gets the command that will be run, as set by
+ * gksu_context_set_command.
+ *
+ * Returns: a string with the command or NULL if not set.
+ */
+const gchar*
+gksu_context_get_command (GksuContext *context)
+{
+  return context->command;
+}
+
+/**
+ * gksu_context_set_login_shell:
+ * @context: the #GksuContext you want to modify
+ * @value: TRUE or FALSE
+ *
+ * Should the shell in which the command will be run be
+ * a login shell?
+ */
+void
+gksu_context_set_login_shell (GksuContext *context, gboolean value)
+{
+  context->login_shell = value;
+}
+
+/**
+ * gksu_context_get_login_shell:
+ * @context: the #GksuContext from which to grab the information
+ *
+ * Finds out if the shell created by the underlying su process
+ * will be a login shell.
+ *
+ * Returns: TRUE if the shell will be a login shell, FALSE otherwise.
+ */
+gboolean
+gksu_context_get_login_shell (GksuContext *context)
+{
+  return context->login_shell;
+}
+
+/**
+ * gksu_context_set_keep_env:
+ * @context: the #GksuContext you want to modify
+ * @value: TRUE or FALSE
+ *
+ * Should the environment be kept as it is? Defaults to
+ * TRUE. Notice that setting this to FALSE may cause the
+ * X authorization stuff to fail.
+ */
+void
+gksu_context_set_keep_env (GksuContext *context, gboolean value)
+{
+  context->keep_env = value;
+}
+
+/**
+ * gksu_context_get_keep_env:
+ * @context: the #GksuContext from which to grab the information
+ *
+ * Finds out if the environment in which the program will be
+ * run will be reset.
+ *
+ * Returns: TRUE if the environment is going to be kept,
+ * FALSE otherwise.
+ */
+gboolean
+gksu_context_get_keep_env (GksuContext *context)
+{
+  return context->keep_env;
+}
+
+/**
+ * gksu_context_set_description:
+ * @context: the #GksuContext you want to modify
+ * @description: a string to set the description for
+ *
+ * Set the nice name for the action that is being run that the window
+ * that asks for the password will have.  This is only meant to be
+ * used if the default window is used, of course.
+ */
+void
+gksu_context_set_description (GksuContext *context, gchar *description)
+{
+  if (context->description)
+    g_free (context->description);
+  context->description = g_strdup (description);
+}
+
+/**
+ * gksu_context_get_description:
+ * @context: the #GksuContext you want to get the description from.
+ *
+ * Get the description that the window will have when the
+ * default function for requesting the password is
+ * called.
+ *
+ * Returns: a string with the description or NULL if not set.
+ */
+gchar*
+gksu_context_get_description (GksuContext *context)
+{
+  return context->description;
+}
+
+/**
+ * gksu_context_set_message:
+ * @context: the #GksuContext you want to modify
+ * @message: a string to set the message for
+ *
+ * Set the message that the window that asks for the password will have.
+ * This is only meant to be used if the default window is used, of course.
+ */
+void
+gksu_context_set_message (GksuContext *context, gchar *message)
+{
+  if (context->message)
+    g_free (context->message);
+  context->message = g_strdup (message);
+}
+
+/**
+ * gksu_context_get_message:
+ * @context: the #GksuContext you want to get the message from.
+ *
+ * Get the message that the window will have when the
+ * default function for requesting the password is
+ * called.
+ *
+ * Returns: a string with the message or NULL if not set.
+ */
+gchar*
+gksu_context_get_message (GksuContext *context)
+{
+  return context->message;
+}
+
+/**
+ * gksu_context_set_alert:
+ * @context: the #GksuContext you want to modify
+ * @alert: a string to set the alert for
+ *
+ * Set the alert that the window that asks for the password will have.
+ * This is only meant to be used if the default window is used, of course.
+ * This alert should be used to display messages such as 'incorrect password',
+ * for instance.
+ */
+void
+gksu_context_set_alert (GksuContext *context, gchar *alert)
+{
+  if (context->alert)
+    g_free (context->alert);
+  context->alert = g_strdup (alert);
+}
+
+/**
+ * gksu_context_get_alert:
+ * @context: the #GksuContext you want to get the alert from.
+ *
+ * Get the alert that the window will have when the
+ * default function for requesting the password is
+ * called.
+ *
+ * Returns: a string with the alert or NULL if not set.
+ */
+gchar*
+gksu_context_get_alert (GksuContext *context)
+{
+  return context->alert;
+}
+
+/**
+ * gksu_context_set_debug:
+ * @context: the #GksuContext you want to modify
+ * @value: TRUE or FALSE
+ *
+ * Set up if debuging information should be printed.
+ */
+void
+gksu_context_set_grab (GksuContext *context, gboolean value)
+{
+  context->grab = value;
+}
+
+/**
+ * gksu_context_get_grab:
+ * @context: the #GksuContext you want to ask whether a grab will be done.
+ *
+ * Returns TRUE if gksu has been asked to do a grab on keyboard and mouse
+ * when asking for the password.
+ *
+ * Returns: TRUE if yes, FALSE otherwise.
+ */
+gboolean
+gksu_context_get_grab (GksuContext *context)
+{
+  return context->grab;
+}
+
+/**
+ * gksu_context_set_always_ask_password:
+ * @context: the #GksuContext you want to modify
+ * @value: TRUE or FALSE
+ *
+ * Set up if gksu should always ask for a password. Notice that this
+ * will only work when passwords are cached, as done by gnome-keyring
+ * for gksu's su mode and by sudo for gksu's sudo mode, but will have no
+ * effect if su or sudo are set up to not require the password at all.
+ */
+void
+gksu_context_set_always_ask_password (GksuContext *context, gboolean value)
+{
+  context->always_ask_password = value;
+}
+
+/**
+ * gksu_context_get_always_ask_password:
+ * @context: the #GksuContext you want to ask whether a grab will be done.
+ *
+ * Returns TRUE if gksu has been asked to always ask for a password 
+ * (even if sudo or gnome-keyring have cached it)
+ *
+ * Returns: TRUE if yes, FALSE otherwise.
+ */
+gboolean
+gksu_context_get_always_ask_password (GksuContext *context)
+{
+   return context->always_ask_password;
+}
+
+
+/**
+ * gksu_context_set_launcher_context:
+ * @context: the #GksuContext you want to set the sn context in
+ * @sn_context: the #SnLauncherContext you want to set
+ *
+ * Tell libgksu to use the given #SnLauncherContext for startup notification.
+ * Currently the library will use this to set DESKTOP_STARTUP_ID in the
+ * environment of the child and to issue initiate and complete events.
+ * Notice that you don't need to use this function unless you want to
+ * override gksu's default behavior on startup notification, since the
+ * library will create its own context.
+ *
+ * Returns: the #SnLauncherContext which is set, or NULL if none was set
+ */
+void
+gksu_context_set_launcher_context (GksuContext *context,
+				   SnLauncherContext *sn_context)
+{
+  if (context->sn_context)
+    sn_launcher_context_unref (context->sn_context);
+  context->sn_context = sn_context;
+}
+
+/**
+ * gksu_context_get_launcher_context:
+ * @context: the #GksuContext you want to get the sn context from
+ *
+ * Gets the current startup notification launcher context
+ *
+ * Returns: the #SnLauncherContext which is set, or NULL if none was set
+ */
+SnLauncherContext*
+gksu_context_get_launcher_context (GksuContext *context)
+{
+  return context->sn_context;
+}
+
+/**
+ * gksu_context_set_launcher_id:
+ * @context: the #GksuContext you want to set the sn id in
+ * @sn_context: the sn_id you want to set, as a #gchar
+ */
+void
+gksu_context_set_launcher_id (GksuContext *context,
+			      gchar *sn_id)
+{
+  if (context->sn_id)
+    g_free (context->sn_id);
+  context->sn_id = g_strdup(sn_id);
+}
+
+/**
+ * gksu_context_launch_initiate:
+ * @context: the #GksuContext you want to initiate the launch for
+ *
+ * Initiates the launch, as far as Startup Notification is concerned;
+ * This will only be used internally, usually.
+ */
+static void
+gksu_context_launch_initiate (GksuContext *context)
+{
+  gchar *sid = NULL;
+  guint32 launch_time = gdk_x11_display_get_user_time (gdk_display_get_default ());
+  static gboolean initiated = FALSE;
+
+  if (!initiated)
+    initiated = TRUE;
+  else
+    return;
+
+  sn_launcher_context_initiate (context->sn_context,
+				g_get_prgname (),
+				gksu_context_get_command (context),
+				launch_time);
+
+  sid = g_strdup_printf ("%s", sn_launcher_context_get_startup_id (context->sn_context));
+  gksu_context_set_launcher_id (context, sid);
+
+  if (context->debug)
+    fprintf (stderr, "STARTUP_ID: %s\n", sid);
+  setenv ("DESKTOP_STARTUP_ID", sid, TRUE);
+  g_free(sid);
+}
+
+/**
+ * gksu_context_launch_complete:
+ * @context: the #GksuContext you want to complete the launch for
+ *
+ * Completes the launch, as far as Startup Notification is concerned;
+ * This will only be used internally, usually.
+ */
+static void
+gksu_context_launch_complete (GksuContext *context)
+{
+  sn_launcher_context_complete(context->sn_context);
+}
+
+/**
+ * gksu_context_set_debug:
+ * @context: the #GksuContext you want to modify
+ * @value: TRUE or FALSE
+ *
+ * Set up if debuging information should be printed.
+ */
+void
+gksu_context_set_debug (GksuContext *context, gboolean value)
+{
+  context->debug = value;
+}
+
+/**
+ * gksu_context_get_debug:
+ * @context: the #GksuContext from which to grab the information
+ *
+ * Finds out if the library is configured to print debuging
+ * information.
+ *
+ * Returns: TRUE if it is, FALSE otherwise.
+ */
+gboolean
+gksu_context_get_debug (GksuContext *context)
+{
+  return context->debug;
+}
+
+/**
+ * gksu_context_free
+ * @context: the #GksuContext to be freed.
+ *
+ * Frees the given #GksuContext.
+ */
+void
+gksu_context_free (GksuContext *context)
+{
+  g_free (context->xauth);
+  g_free (context->dir);
+  g_free (context->display);
+
+  g_object_unref (context->gconf_client);
+
+  g_free (context->description);
+  g_free (context->message);
+
+  g_free (context->user);
+  g_free (context->command);
+
+  g_free (context);
+}
+
+/**
+ * gksu_context_ref
+ * @context: A #GksuContext struct.
+ *
+ * Increments the reference count of the given #GksuContext.
+ */
+GksuContext*
+gksu_context_ref (GksuContext *context)
+{
+  context->ref_count++;
+  return context;
+}
+
+/**
+ * gksu_context_unref
+ * @context: A #GksuContext struct.
+ *
+ * Decrements the reference count of the given #GksuContext struct,
+ * freeing it if the reference count falls to zero.
+ */
+void
+gksu_context_unref (GksuContext *context)
+{
+  if (--context->ref_count == 0)
+    {
+        gksu_context_free (context);
+    }
+}
+
+GType
+gksu_context_get_type (void)
+{
+  static GType type_gksu_context = 0;
+
+  if (!type_gksu_context)
+    type_gksu_context = g_boxed_type_register_static
+      ("GksuContext", 
+       (GBoxedCopyFunc) gksu_context_ref,
+       (GBoxedFreeFunc) gksu_context_unref);
+
+  return type_gksu_context;
+}
+
+
+/**
+ * gksu_su_full:
+ * @context: a #GksuContext
+ * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
+ * requesting a password is necessary; it may be NULL, in which case
+ * the standard password request dialog will be used
+ * @ask_pass_data: a #gpointer with user data to be passed to the
+ * #GksuAskPasswordFunc
+ * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
+ * when the command is being run without the need for requesting
+ * a password; it will only be called if the display-no-pass-info
+ * gconf key is enabled; NULL will have the standard dialog be shown
+ * @pass_not_needed_data: a #gpointer with the user data to be passed to the
+ * #GksuPasswordNotNeededFunc
+ * @error: a #GError object to be filled with the error code or NULL
+ *
+ * This is a compatibility shim over gksu_su_fuller, which, for
+ * compatibility reasons, lacks the 'exit_status' argument. You should
+ * check the documentation for gksu_su_fuller for information about
+ * the arguments.
+ *
+ * Returns: TRUE if all went fine, FALSE if failed
+ */
+
+gboolean
+gksu_su_full (GksuContext *context,
+	      GksuAskPassFunc ask_pass,
+	      gpointer ask_pass_data,
+	      GksuPassNotNeededFunc pass_not_needed,
+	      gpointer pass_not_needed_data,
+	      GError **error)
+{
+  return gksu_su_fuller(context,
+  			ask_pass, ask_pass_data,
+			pass_not_needed, pass_not_needed_data,
+			NULL, error);
+}
+
+
+/**
+ * gksu_su_fuller:
+ * @context: a #GksuContext
+ * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
+ * requesting a password is necessary; it may be NULL, in which case
+ * the standard password request dialog will be used
+ * @ask_pass_data: a #gpointer with user data to be passed to the
+ * #GksuAskPasswordFunc
+ * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
+ * when the command is being run without the need for requesting
+ * a password; it will only be called if the display-no-pass-info
+ * gconf key is enabled; NULL will have the standard dialog be shown
+ * @pass_not_needed_data: a #gpointer with the user data to be passed to the
+ * #GksuPasswordNotNeededFunc
+ * @exit_status: an optional pointer to a #gint8 which will be filled with
+ * the exit status of the child process
+ * @error: a #GError object to be filled with the error code or NULL
+ *
+ * This could be considered one of the main functions in GKSu.
+ * it is responsible for doing the 'user changing' magic calling
+ * the #GksuAskPassFunc function to request a password if needed.
+ * and the #GksuPassNotNeededFunc function if a password won't be
+ * needed, so the application has the oportunity of warning the user
+ * what it's doing.
+ *
+ * This function uses su as backend.
+ *
+ * Returns: TRUE if all went fine, FALSE if failed
+ */
+gboolean
+gksu_su_fuller (GksuContext *context,
+	        GksuAskPassFunc ask_pass,
+	        gpointer ask_pass_data,
+	        GksuPassNotNeededFunc pass_not_needed,
+	        gpointer pass_not_needed_data,
+	        gint8 *exit_status,
+	        GError **error)
+{
+  GQuark gksu_quark;
+  int i = 0;
+
+  gchar auxcommand[] = PREFIX "/lib/" PACKAGE "/gksu-run-helper";
+
+  int fdpty;
+  pid_t pid;
+
+  context->sudo_mode = FALSE;
+
+  gksu_quark = g_quark_from_string (PACKAGE);
+
+  if (!context->command)
+    {
+      g_set_error (error, gksu_quark, GKSU_ERROR_NOCOMMAND,
+		   _("gksu_run needs a command to be run, "
+		     "none was provided."));
+      return FALSE;
+    }
+
+  if (!context->user)
+    context->user = g_strdup ("root");
+
+  if (!g_file_test (auxcommand, G_FILE_TEST_IS_EXECUTABLE))
+    {
+      g_set_error (error, gksu_quark, GKSU_ERROR_HELPER,
+		   _("The gksu-run-helper command was not found or "
+		     "is not executable."));
+      return FALSE;
+    }
+
+  if (!prepare_xauth (context))
+    {
+      g_set_error (error, gksu_quark, GKSU_ERROR_XAUTH,
+		   _("Unable to copy the user's Xauthorization file."));
+      return FALSE;
+    }
+
+  if (context->sn_context)
+    gksu_context_launch_initiate (context);
+
+  pid = forkpty(&fdpty, NULL, NULL, NULL);
+  if (pid == 0)
+    {
+      gchar **cmd = g_malloc (sizeof(gchar*)*7);
+
+      setsid();   // make us session leader
+      cmd[i] = g_strdup ("/bin/su"); i++;
+      if (context->login_shell)
+	{
+	  cmd[i] = g_strdup ("-"); i++;
+	}
+      cmd[i] = g_strdup (context->user); i++;
+      if (context->keep_env)
+	{
+	  cmd[i] = g_strdup ("-p"); i++;
+	}
+      cmd[i] = g_strdup ("-c"); i++;
+
+      /* needs to get X authorization prior to running the program */
+      cmd[i] = g_strdup_printf ("%s \"%s\"", auxcommand,
+				context->command); i++;
+
+      cmd[i] = NULL;
+
+      /* executes the command */
+      if (execv (cmd[0], cmd) == -1)
+	{
+	  fprintf (stderr,
+		   "Unable to run /bin/su: %s",
+		   strerror(errno));
+	}
+
+      for (i = 0 ; cmd[i] != NULL ; i++)
+	g_free (cmd[i]);
+      g_free(cmd);
+    }
+  else if (pid == -1)
+    {
+      g_set_error (error, gksu_quark, GKSU_ERROR_FORK,
+		   _("Failed to fork new process: %s"),
+		   strerror(errno));
+      return FALSE;
+    }
+  else
+    {
+      fd_set rfds;
+
+      struct timeval tv;
+
+      struct passwd *pwd = NULL;
+      gint target_uid = -1;
+      gint my_uid = 0;
+
+      gchar buf[256] = {0};
+      gint status;
+
+      gchar *password = NULL;
+      gchar *cmdline = NULL;
+      gboolean password_needed = FALSE;
+      gboolean used_gnome_keyring = FALSE;
+
+      my_uid = getuid();
+      pwd = getpwnam (context->user);
+      if (pwd)
+	target_uid = pwd->pw_uid;
+
+      if (ask_pass == NULL)
+	{
+	  ask_pass = su_ask_password;
+	}
+
+      if (pass_not_needed == NULL)
+	{
+	  pass_not_needed = no_pass;
+	}
+
+      /* no need to ask for password if we're already root */
+      if (my_uid != target_uid && my_uid)
+	{
+	  gint count;
+	  struct termios tio;
+
+	  read (fdpty, buf, 255);
+	  if (context->debug)
+	    fprintf (stderr, "gksu_context_run: buf: -%s-\n", buf);
+
+	  /* make sure we notice that ECHO is turned off, if it gets
+	     turned off */
+	  tcgetattr (fdpty, &tio);
+	  for (count = 0; (tio.c_lflag & ECHO) && count < 15; count++)
+	    {
+	      usleep (1000);
+	      tcgetattr (fdpty, &tio);
+	    }
+
+	  if (!(tio.c_lflag & ECHO))
+	    {
+	      gboolean prompt_grab;
+	      prompt_grab = gconf_client_get_bool (context->gconf_client, BASE_PATH "prompt",
+						   NULL);
+
+	      if (prompt_grab)
+		gksu_prompt_grab (context);
+
+              /* try to get the password from the GNOME Keyring first, but
+	       * only if we have not been requested to always ask for the
+	       * password
+	       */
+	      if (!context->always_ask_password)
+	        password = get_gnome_keyring_password (context);
+	      if (password == NULL)
+		{
+		  password = ask_pass (context, buf, ask_pass_data, error);
+		  if (context->debug)
+		    {
+		      fprintf (stderr, "no password on keyring\n");
+		      if (password == NULL)
+			fprintf (stderr, "no password from ask_pass!\n");
+		    }
+		}
+	      else
+		{
+		  if (context->debug)
+		    fprintf (stderr, "password from keyring found\n");
+		  used_gnome_keyring = TRUE;
+		}
+	      if (password == NULL || (error && (*error)))
+		{
+		  if (context->debug)
+		    fprintf (stderr, "gksu_su_full: problem getting password - getting out\n");
+		  if (context->debug && error)
+		    fprintf (stderr, "error: %s\n", (*error)->message);
+		  nullify_password (password);
+		  return TRUE;
+		}
+
+	      write (fdpty, password, strlen(password) + 1);
+	      write (fdpty, "\n", 1);
+	      password_needed = TRUE;
+	    }
+	}
+
+      if (context->debug)
+	fprintf (stderr, "DEBUG (run:after-pass) buf: -%s-\n", buf);
+      if (strncmp (buf, "gksu", 4) && strncmp (buf, "su", 2))
+	{
+	  /* drop the \n echoed on password entry if su did request
+	     a password */
+	  if (password_needed)
+	    read (fdpty, buf, 255);
+	  if (context->debug)
+	    fprintf (stderr, "DEBUG (run:post-after-pass) buf: -%s-\n", buf);
+	  read (fdpty, buf, 255);
+	  if (context->debug)
+	    fprintf (stderr, "DEBUG (run:post-after-pass) buf: -%s-\n", buf);
+	}
+
+      FD_ZERO (&rfds);
+      FD_SET (fdpty, &rfds);
+      tv.tv_sec = 1;
+      tv.tv_usec = 0;
+      int loop_count = 0;
+      while (TRUE)
+	{
+	  int retval = 0;
+
+	  if (!strncmp (buf, "su", 2))
+	    {
+	      gchar **strings;
+
+	      if (password)
+		{
+		  nullify_password (password);
+		  unset_gnome_keyring_password (context);
+		}
+
+	      strings = g_strsplit (buf, ":", 2);
+	      if (strings[1] && !strncmp (strings[1], " Authentication failure", 23))
+		{
+		  if (used_gnome_keyring)
+		    g_set_error (error, gksu_quark,
+				 GKSU_ERROR_WRONGAUTOPASS,
+				 _("Wrong password got from keyring."));
+		  else
+		    g_set_error (error, gksu_quark,
+				 GKSU_ERROR_WRONGPASS,
+				 _("Wrong password."));
+		}
+	      g_strfreev (strings);
+
+	      if (context->debug)
+		fprintf (stderr, "DEBUG (auth_failed) buf: -%s-\n", buf);
+
+	      break;
+	    }
+	  else if (!strncmp (buf, "gksu: waiting", 13))
+	    {
+	      gchar *line;
+
+	      if (password)
+		{
+		  set_gnome_keyring_password (context, password);
+		  nullify_password (password);
+		}
+
+	      if (context->debug)
+		fprintf (stderr, "DEBUG (gksu: waiting) buf: -%s-\n", buf);
+
+	      line = g_strdup_printf ("gksu-run: %s\n", context->display);
+	      write (fdpty, line, strlen(line));
+	      g_free (line);
+
+	      line = g_strdup_printf ("gksu-run: %s\n", context->sn_id);
+	      write (fdpty, line, strlen(line));
+	      g_free (line);
+
+	      line = g_strdup_printf ("gksu-run: %s\n", context->xauth);
+	      write (fdpty, line, strlen(line));
+	      g_free (line);
+
+	      tcdrain (fdpty);
+
+	      bzero (buf, 256);
+	      read (fdpty, buf, 255);
+
+	      break;
+	    }
+
+	  retval = select (fdpty + 1, &rfds, NULL, NULL, &tv);
+	  if ((loop_count > 50) || (!retval))
+	    {
+	      gchar *emsg = NULL;
+	      gchar *converted_str = NULL;
+	      GError *converr = NULL;
+
+	      if (password)
+		nullify_password (password);
+
+	      converted_str = g_locale_to_utf8 (buf, -1, NULL, NULL, &converr);
+	      if (converr)
+		{
+		  g_warning (_("Failed to communicate with "
+			       "gksu-run-helper.\n\n"
+			       "Received:\n"
+			       " %s\n"
+			       "While expecting:\n"
+			       " %s"), buf, "gksu: waiting");
+		  emsg = g_strdup_printf (_("Failed to communicate with "
+					    "gksu-run-helper.\n\n"
+					    "Received bad string "
+					    "while expecting:\n"
+					    " %s"), "gksu: waiting");
+		  g_error_free (converr);
+		}
+	      else
+		emsg = g_strdup_printf (_("Failed to communicate with "
+					  "gksu-run-helper.\n\n"
+					  "Received:\n"
+					  " %s\n"
+					  "While expecting:\n"
+					  " %s"), converted_str, "gksu: waiting");
+	      g_free (converted_str);
+
+	      g_set_error (error, gksu_quark, GKSU_ERROR_HELPER, emsg);
+	      g_free (emsg);
+
+	      if (context->debug)
+		fprintf (stderr, "DEBUG (failed!) buf: -%s-\n", buf);
+
+	      return FALSE;
+	    }
+	  else if (retval == -1)
+	    {
+	      if (context->debug)
+		fprintf (stderr, "DEBUG (select failed!) buf: %s\n", buf);
+	      return FALSE;
+	    }
+
+	  read (fdpty, buf, 255);
+	  if (context->debug)
+	    fprintf (stderr, "DEBUG (run:after-pass) buf: -%s-\n", buf);
+	  loop_count++;
+	}
+
+      if (!password_needed || used_gnome_keyring)
+	{
+	  gboolean should_display;
+
+	  should_display = gconf_client_get_bool (context->gconf_client,
+						  BASE_PATH "display-no-pass-info", NULL);
+
+	  /* configuration tells us to show this message */
+	  if (should_display)
+	    {
+	      if (context->debug)
+		fprintf (stderr, "Calling pass_not_needed window...\n");
+	      pass_not_needed (context, pass_not_needed_data);
+	      /* make sure it is displayed */
+	      while (gtk_events_pending ())
+		gtk_main_iteration ();
+	    }
+	}
+
+      cmdline = g_strdup("bin/su");
+      /* wait for the child process to end or become something other
+	 than su */
+      pid_t pid_exited;
+      while ((!(pid_exited = waitpid (pid, &status, WNOHANG))) &&
+	     (g_str_has_suffix(cmdline, "bin/su")))
+	{
+	  if (cmdline)
+	    g_free (cmdline);
+	  cmdline = get_process_name (pid);
+	  usleep(100000);
+	}
+
+      if (context->sn_context)
+	gksu_context_launch_complete (context);
+
+      bzero(buf, 256);
+      while (read (fdpty, buf, 255) > 0)
+	{
+	  fprintf (stderr, "%s", buf);
+	  bzero(buf, 256);
+	}
+
+      if (pid_exited != pid)
+	waitpid(pid, &status, 0);
+
+      if (exit_status)
+      {
+      	if (WIFEXITED(status)) {
+      	  *exit_status = WEXITSTATUS(status);
+	} else if (WIFSIGNALED(status)) {
+	  *exit_status = -1;
+	}
+      }
+
+      if (WEXITSTATUS(status))
+	{
+	  if(cmdline)
+	    {
+	      /* su already exec()ed something else, don't report
+	       * exit status errors in that case
+	       */
+	      if (!g_str_has_suffix (cmdline, "su"))
+		{
+		  g_free (cmdline);
+		  return FALSE;
+		}
+	      g_free (cmdline);
+	    }
+
+	  if (error == NULL)
+	    g_set_error (error, gksu_quark,
+			 GKSU_ERROR_CHILDFAILED,
+			 _("su terminated with %d status"),
+			 WEXITSTATUS(status));
+	}
+    }
+
+  if (error)
+    return FALSE;
+
+  return TRUE;
+}
+
+/**
+ * gksu_su
+ * @command_line: the command line that will be executed as other user
+ * @error: a #GError to be set with the error condition, if an error
+ * happens
+ *
+ * This function is a wrapper for gksu_su_run_full. It will call it
+ * without giving the callback functions, which leads to the standard
+ * ones being called. A simple #GksuContext is created to hold the
+ * user name and the command.
+ *
+ * Returns: TRUE if all went well, FALSE if an error happend.
+ */
+gboolean
+gksu_su (gchar *command_line, GError **error)
+{
+  GksuContext *context = gksu_context_new ();
+  gboolean retval;
+
+  context->command = g_strdup (command_line);
+  context->user = g_strdup ("root");
+  retval = gksu_su_full (context,
+			 NULL, NULL,
+			 NULL, NULL,
+			 error);
+  gksu_context_free (context);
+  return retval;
+}
+
+static void
+read_line (int fd, gchar *buffer, int n)
+{
+  gint counter = 0;
+  gchar tmp[2] = {0};
+
+  for (; counter < (n - 1); counter++)
+    {
+      read (fd, tmp, 1);
+      if (tmp[0] == '\n')
+	break;
+      buffer[counter] = tmp[0];
+    }
+  buffer[counter+1] = '\0';
+}
+
+/**
+ * gksu_sudo_full:
+ * @context: a #GksuContext
+ * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
+ * requesting a password is necessary; it may be NULL, in which case
+ * the standard password request dialog will be used
+ * @ask_pass_data: a #gpointer with user data to be passed to the
+ * #GksuAskPasswordFunc
+ * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
+ * when the command is being run without the need for requesting
+ * a password; it will only be called if the display-no-pass-info
+ * gconf key is enabled; NULL will have the standard dialog be shown
+ * @pass_not_needed_data: a #gpointer with the user data to be passed to the
+ * #GksuPasswordNotNeededFunc
+ * @error: a #GError object to be filled with the error code or NULL
+ *
+ * This is a compatibility shim over gksu_sudo_fuller, which, for
+ * compatibility reasons, lacks the 'exit_status' argument. You should
+ * check the documentation for gksu_sudo_fuller for information about
+ * the arguments.
+ *
+ * Returns: TRUE if all went fine, FALSE if failed
+ */
+
+gboolean
+gksu_sudo_full (GksuContext *context,
+		GksuAskPassFunc ask_pass,
+		gpointer ask_pass_data,
+		GksuPassNotNeededFunc pass_not_needed,
+		gpointer pass_not_needed_data,
+		GError **error)
+{
+  return gksu_sudo_fuller(context,
+  			  ask_pass, ask_pass_data,
+			  pass_not_needed, pass_not_needed_data,
+			  NULL, error);
+}
+
+/**
+ * gksu_sudo_fuller:
+ * @context: a #GksuContext
+ * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
+ * requesting a password is necessary; it may be NULL, in which case
+ * the standard password request dialog will be used
+ * @ask_pass_data: a #gpointer with user data to be passed to the
+ * #GksuAskPasswordFunc
+ * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
+ * when the command is being run without the need for requesting
+ * a password; it will only be called if the display-no-pass-info
+ * gconf key is enabled; NULL will have the standard dialog be shown
+ * @pass_not_needed_data: a #gpointer with the user data to be passed to the
+ * #GksuPasswordNotNeededFunc
+ * @error: a #GError object to be filled with the error code or NULL
+ * @exit_status: an optional pointer to a #gint8 which will be filled with
+ * the exit status of the child process
+ *
+ * This could be considered one of the main functions in GKSu.
+ * it is responsible for doing the 'user changing' magic calling
+ * the #GksuAskPassFunc function to request a password if needed.
+ * and the #GksuPassNotNeededFunc function if a password won't be
+ * needed, so the application has the oportunity of warning the user
+ * what it's doing.
+ *
+ * This function uses the sudo backend.
+ *
+ * Returns: TRUE if all went fine, FALSE if failed
+ */
+gboolean
+gksu_sudo_fuller (GksuContext *context,
+		  GksuAskPassFunc ask_pass,
+		  gpointer ask_pass_data,
+		  GksuPassNotNeededFunc pass_not_needed,
+		  gpointer pass_not_needed_data,
+		  gint8 *exit_status,
+		  GError **error)
+{
+  char **cmd;
+  char buffer[256] = {0};
+  int argcount = 8;
+  int i, j;
+
+  GQuark gksu_quark;
+
+  gchar *xauth = NULL,
+    *xauth_env = NULL;
+
+  pid_t pid;
+  int status;
+  FILE *infile, *outfile;
+  int parent_pipe[2];	/* For talking to the parent */
+  int child_pipe[2];	/* For talking to the child */
+
+  context->sudo_mode = TRUE;
+
+  gksu_quark = g_quark_from_string (PACKAGE);
+
+  if (!context->command)
+    {
+      g_set_error (error, gksu_quark, GKSU_ERROR_NOCOMMAND,
+		   _("gksu_sudo_run needs a command to be run, "
+		     "none was provided."));
+      return FALSE;
+    }
+
+  if (!context->user)
+    context->user = g_strdup ("root");
+
+  if (ask_pass == NULL)
+    {
+      if (context->debug)
+	fprintf (stderr, "No ask_pass set, using default!\n");
+      ask_pass = su_ask_password;
+    }
+  if (pass_not_needed == NULL)
+    {
+      pass_not_needed = no_pass;
+    }
+
+  if (context->always_ask_password)
+    {
+       gint exit_status;
+       g_spawn_command_line_sync("/usr/bin/sudo -K", NULL, NULL, &exit_status, NULL);
+    }
+
+
+  /*
+     FIXME: need to set GError in a more detailed way
+  */
+  if (!sudo_prepare_xauth (context))
+    {
+      g_set_error (error, gksu_quark, GKSU_ERROR_XAUTH,
+		   _("Unable to copy the user's Xauthorization file."));
+      return FALSE;
+    }
+
+  /* sets XAUTHORITY */
+  xauth = g_strdup_printf ("%s/.Xauthority", context->dir);
+  xauth_env = getenv ("XAUTHORITY");
+  setenv ("XAUTHORITY", xauth, TRUE);
+  if (context->debug)
+    fprintf (stderr, "xauth: %s\n", xauth);
+
+  /* set startup id */
+  if (context->sn_context)
+    gksu_context_launch_initiate (context);
+
+  cmd = g_new (gchar *, argcount + 1);
+
+  argcount = 0;
+
+  /* sudo binary */
+  cmd[argcount] = g_strdup("/usr/bin/sudo");
+  argcount++;
+
+  if (!context->keep_env)
+    {
+      /* Make sudo set $HOME */
+      cmd[argcount] = g_strdup("-H");
+      argcount++;
+    }
+
+  /* Make sudo read from stdin */
+  cmd[argcount] = g_strdup("-S");
+  argcount++;
+
+  /* Make sudo use next arg as prompt */
+  cmd[argcount] = g_strdup("-p");
+  argcount++;
+
+  /* prompt */
+  cmd[argcount] = g_strdup("GNOME_SUDO_PASS");
+  argcount++;
+
+  /* Make sudo use the selected user */
+  cmd[argcount] = g_strdup("-u");
+  argcount++;
+
+  /* user */
+  cmd[argcount] = g_strdup(context->user);
+  argcount++;
+
+  /* sudo does not understand this if we do not use -H
+     weird.
+  */
+  if (!context->keep_env)
+    {
+      /* Make sudo stop processing options */
+      cmd[argcount] = g_strdup("--");
+      argcount++;
+    }
+
+  {
+    gchar *tmp_arg = g_malloc (sizeof(gchar)*1);
+    gboolean inside_quotes = FALSE;
+
+    tmp_arg[0] = '\0';
+
+    for (i = j = 0; ; i++)
+      {
+	if ((context->command[i] == '\'') && (context->command[i-1] != '\\'))
+	  {
+	    i = i + 1;
+	    inside_quotes = !inside_quotes;
+	  }
+
+	if ((context->command[i] == ' ' && inside_quotes == FALSE)
+	    || context->command[i] == '\0')
+	  {
+	    tmp_arg = g_realloc (tmp_arg, sizeof(gchar)*(j+1));
+	    tmp_arg[j] = '\0';
+	    cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
+	    cmd[argcount] = g_strdup (tmp_arg);
+
+	    g_free (tmp_arg);
+
+	    argcount = argcount + 1;
+	    j = 0;
+
+	    if (context->command[i] == '\0')
+	      break;
+
+	    tmp_arg = g_malloc (sizeof(gchar)*1);
+	    tmp_arg[0] = '\0';
+	  }
+	else
+	  {
+	    if (context->command[i] == '\\' && context->command[i+1] != '\\')
+	      i = i + 1;
+	    tmp_arg = g_realloc (tmp_arg, sizeof(gchar)*(j+1));
+	    tmp_arg[j] = context->command[i];
+	    j = j + 1;
+	  }
+      }
+  }
+  cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
+  cmd[argcount] = NULL;
+
+  if (context->debug)
+    {
+      for (i = 0; cmd[i] != NULL; i++)
+	fprintf (stderr, "cmd[%d]: %s\n", i, cmd[i]);
+    }
+
+  if ((pipe(parent_pipe)) == -1)
+    {
+      g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
+		   _("Error creating pipe: %s"),
+		   strerror(errno));
+      sudo_reset_xauth (context, xauth, xauth_env);
+      return FALSE;
+    }
+
+  if ((pipe(child_pipe)) == -1)
+    {
+      g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
+		   _("Error creating pipe: %s"),
+		   strerror(errno));
+      sudo_reset_xauth (context, xauth, xauth_env);
+      return FALSE;
+    }
+
+  pid = fork();
+  if (pid == -1)
+    {
+      g_set_error (error, gksu_quark, GKSU_ERROR_FORK,
+		   _("Failed to fork new process: %s"),
+		   strerror(errno));
+      sudo_reset_xauth (context, xauth, xauth_env);
+      return FALSE;
+    }
+  else if (pid == 0)
+    {
+      // Child
+      setsid();   // make us session leader
+      close(child_pipe[1]);
+      dup2(child_pipe[0], STDIN_FILENO);
+      dup2(parent_pipe[1], STDERR_FILENO);
+
+      execv(cmd[0], cmd);
+
+      g_set_error (error, gksu_quark, GKSU_ERROR_EXEC,
+		   _("Failed to exec new process: %s"),
+		   strerror(errno));
+      sudo_reset_xauth (context, xauth, xauth_env);
+      return FALSE;
+    }
+  else
+    {
+      gint counter = 0;
+      gchar *cmdline = NULL;
+
+      // Parent
+      close(parent_pipe[1]);
+
+      infile = fdopen(parent_pipe[0], "r");
+      if (!infile)
+	{
+	  g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
+		       _("Error opening pipe: %s"),
+		       strerror(errno));
+	  sudo_reset_xauth (context, xauth, xauth_env);
+	  return FALSE;
+	}
+
+      outfile = fdopen(child_pipe[1], "w");
+      if (!outfile)
+	{
+	  g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
+		       _("Error opening pipe: %s"),
+		       strerror(errno));
+	  sudo_reset_xauth (context, xauth, xauth_env);
+	  return FALSE;
+	}
+
+      /*
+	we are expecting to receive a GNOME_SUDO_PASS
+	if we don't there are two possibilities: an error
+	or a password is not needed
+      */
+      fcntl (parent_pipe[0], F_SETFL, O_NONBLOCK);
+
+      { /* no matter if we can read, since we're using
+	   O_NONBLOCK; this is just to avoid the prompt
+	   showing up after the read */
+	fd_set rfds;
+	struct timeval tv;
+
+	FD_ZERO(&rfds);
+	FD_SET(parent_pipe[0], &rfds);
+	tv.tv_sec = 1;
+	tv.tv_usec = 0;
+
+	select (parent_pipe[0] + 1, &rfds, NULL, NULL, &tv);
+      }
+
+      /* Try hard to find the prompt; it may happen that we're
+       * seeing sudo's lecture, or that some pam module is spitting
+       * debugging stuff at the screen
+       */
+      for (counter = 0; counter < 50; counter++)
+	{
+	  if (strncmp (buffer, "GNOME_SUDO_PASS", 15) == 0)
+	    break;
+
+	  read_line (parent_pipe[0], buffer, 256);
+
+	  if (context->debug)
+	    fprintf (stderr, "buffer: -%s-\n", buffer);
+
+	  usleep(1000);
+	}
+
+      if (context->debug)
+	fprintf (stderr, "brute force GNOME_SUDO_PASS ended...\n");
+
+      if (strncmp(buffer, "GNOME_SUDO_PASS", 15) == 0)
+	{
+	  gchar *password = NULL;
+	  gboolean prompt_grab;
+
+	  if (context->debug)
+	    fprintf (stderr, "Yeah, we're in...\n");
+
+	  prompt_grab = gconf_client_get_bool (context->gconf_client, BASE_PATH "prompt",
+						   NULL);
+	  if (prompt_grab)
+	    gksu_prompt_grab (context);
+
+	  password = ask_pass (context, _("Password: "),
+			       ask_pass_data, error);
+	  if (password == NULL || (*error))
+	    {
+	      nullify_password (password);
+	      return FALSE;
+	    }
+
+	  usleep (1000);
+
+	  fprintf (outfile, "%s\n", password);
+	  fclose (outfile);
+
+	  nullify_password (password);
+
+	  /* turn NONBLOCK off */
+	  fcntl(parent_pipe[0], F_SETFL, fcntl(parent_pipe[0], F_GETFL) & ~O_NONBLOCK);
+	  /* ignore the first newline that comes right after sudo receives
+	     the password */
+	  fgets (buffer, 255, infile);
+	  /* this is the status we are interessted in */
+	  fgets (buffer, 255, infile);
+	}
+      else
+	{
+	  gboolean should_display;
+	  if (context->debug)
+	    fprintf (stderr, "No password prompt found; we'll assume we don't need a password.\n");
+
+          /* turn NONBLOCK off, also if have no prompt */
+          fcntl(parent_pipe[0], F_SETFL, fcntl(parent_pipe[0], F_GETFL) & ~O_NONBLOCK);
+
+	  should_display = gconf_client_get_bool (context->gconf_client,
+						  BASE_PATH "display-no-pass-info", NULL);
+
+	  /* configuration tells us to show this message */
+	  if (should_display)
+	    {
+	      if (context->debug)
+		fprintf (stderr, "Calling pass_not_needed window...\n");
+	      pass_not_needed (context, pass_not_needed_data);
+	      /* make sure it is displayed */
+	      while (gtk_events_pending ())
+		gtk_main_iteration ();
+	    }
+
+	  fprintf (stderr, "%s", buffer);
+	}
+
+      if (!strcmp (buffer, "Sorry, try again.\n"))
+	g_set_error (error, gksu_quark, GKSU_ERROR_WRONGPASS,
+		     _("Wrong password."));
+      else if (!strncmp (buffer, "Sorry, user ", 12))
+	g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
+		     _("The underlying authorization mechanism (sudo) "
+		       "does not allow you to run this program. Contact "
+		       "the system administrator."));
+      else
+	{
+	  gchar *haystack = buffer;
+	  gchar *needle;
+
+	  needle = g_strstr_len (haystack, strlen (haystack), " ");
+	  if (needle && (needle + 1))
+	    {
+	      needle += 1;
+	      if (!strncmp (needle, "is not in", 9))
+		g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
+			     _("The underlying authorization mechanism (sudo) "
+			       "does not allow you to run this program. Contact "
+			       "the system administrator."));
+	    }
+	}
+
+      cmdline = g_strdup("sudo");
+      /* wait for the child process to end or become something other
+	 than sudo */
+      pid_t pid_exited;
+      while ((!(pid_exited = waitpid (pid, &status, WNOHANG))) &&
+	     (g_str_has_suffix(cmdline, "sudo")))
+	{
+	  if (cmdline)
+	    g_free (cmdline);
+	  cmdline = get_process_name (pid);
+	  usleep(100000);
+	}
+
+      if (context->sn_context)
+	gksu_context_launch_complete (context);
+
+      while (read (parent_pipe[0], buffer, 255) > 0)
+	{
+	  fprintf (stderr, "%s", buffer);
+	  bzero(buffer, 256);
+	}
+
+      /* if the process is still active waitpid() on it */
+      if (pid_exited != pid)
+	waitpid(pid, &status, 0);
+      sudo_reset_xauth (context, xauth, xauth_env);
+
+      if (exit_status)
+      {
+      	if (WIFEXITED(status)) {
+      	  *exit_status = WEXITSTATUS(status);
+	} else if (WIFSIGNALED(status)) {
+	  *exit_status = -1;
+	}
+      }
+
+      if (WEXITSTATUS(status))
+	{
+	  if(cmdline)
+	    {
+	      /* sudo already exec()ed something else, don't report
+	       * exit status errors in that case
+	       */
+	      if (!g_str_has_suffix (cmdline, "sudo"))
+		{
+		  g_free (cmdline);
+		  return FALSE;
+		}
+	      g_free (cmdline);
+	    }
+	  if (error == NULL)
+	    g_set_error (error, gksu_quark,
+			 GKSU_ERROR_CHILDFAILED,
+			 _("sudo terminated with %d status"),
+			 WEXITSTATUS(status));
+	}
+    }
+
+  /* if error is set we have found an error condition */
+  if (error)
+    return FALSE;
+
+  return TRUE;
+}
+
+/**
+ * gksu_sudo
+ * @command_line: the command line that will be executed as other user
+ * @error: a #GError to be set with the error condition, if an error
+ * happens
+ *
+ * This function is a wrapper for gksu_sudo_run_full. It will call it
+ * without giving the callback functions, which leads to the standard
+ * ones being called. A simple #GksuContext is created to hold the
+ * user name and the command.
+ *
+ * Returns: TRUE if all went well, FALSE if an error happend.
+ */
+gboolean
+gksu_sudo (gchar *command_line,
+	   GError **error)
+{
+  GksuContext *context = gksu_context_new ();
+  gboolean retval;
+
+  context->command = g_strdup (command_line);
+  context->user = g_strdup ("root");
+  retval = gksu_sudo_full (context,
+			   NULL, NULL,
+			   NULL, NULL,
+			   error);
+  gksu_context_free (context);
+
+  return retval;
+}
+
+/**
+ * gksu_run_full:
+ * @context: a #GksuContext
+ * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
+ * requesting a password is necessary; it may be NULL, in which case
+ * the standard password request dialog will be used
+ * @ask_pass_data: a #gpointer with user data to be passed to the
+ * #GksuAskPasswordFunc
+ * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
+ * when the command is being run without the need for requesting
+ * a password; it will only be called if the display-no-pass-info
+ * gconf key is enabled; NULL will have the standard dialog be shown
+ * @pass_not_needed_data: a #gpointer with the user data to be passed to the
+ * #GksuPasswordNotNeededFunc
+ * @error: a #GError object to be filled with the error code or NULL
+ *
+ * This is a compatibility shim over gksu_run_fuller, which, for
+ * compatibility reasons, lacks the 'exit_status' argument.
+ *
+ * Returns: TRUE if all went fine, FALSE if failed
+ */
+
+gboolean
+gksu_run_full (GksuContext *context,
+	       GksuAskPassFunc ask_pass,
+	       gpointer ask_pass_data,
+	       GksuPassNotNeededFunc pass_not_needed,
+	       gpointer pass_not_needed_data,
+	       GError **error)
+{
+  return gksu_run_fuller(context,
+  			 ask_pass, ask_pass_data,
+			 pass_not_needed, pass_not_needed_data,
+			 NULL, error);
+}
+
+/**
+ * gksu_run_fuller:
+ * @context: a #GksuContext
+ * @ask_pass: a #GksuAskPassFunc to be called when the lib determines
+ * requesting a password is necessary; it may be NULL, in which case
+ * the standard password request dialog will be used
+ * @ask_pass_data: a #gpointer with user data to be passed to the
+ * #GksuAskPasswordFunc
+ * @pass_not_needed: a #GksuPassNotNeededFunc that will be called
+ * when the command is being run without the need for requesting
+ * a password; it will only be called if the display-no-pass-info
+ * gconf key is enabled; NULL will have the standard dialog be shown
+ * @pass_not_needed_data: a #gpointer with the user data to be passed to the
+ * #GksuPasswordNotNeededFunc
+ * @exit_status: an optional pointer to a #gint8 which will be filled with
+ * the exit status of the child process
+ * @error: a #GError object to be filled with the error code or NULL
+ *
+ * This function is a wrapper for gksu_sudo_full/gksu_su_full. It will
+ * call one of them, depending on the GConf key that defines whether
+ * the default behavior for gksu is su or sudo mode. This is the
+ * recommended way of using the library functionality.
+ *
+ * Returns: TRUE if all went fine, FALSE if failed
+ */
+gboolean
+gksu_run_fuller (GksuContext *context,
+	         GksuAskPassFunc ask_pass,
+	         gpointer ask_pass_data,
+	         GksuPassNotNeededFunc pass_not_needed,
+	         gpointer pass_not_needed_data,
+		 gint8 *exit_status,
+	         GError **error)
+{
+  GConfClient *gconf_client;
+  gboolean sudo_mode;
+
+  gconf_client = gconf_client_get_default ();
+  sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
+				     NULL);
+  g_object_unref (gconf_client);
+
+  if (sudo_mode)
+    return gksu_sudo_fuller (context, ask_pass, ask_pass_data,
+			     pass_not_needed, pass_not_needed_data,
+			     exit_status, error);
+
+  return gksu_su_fuller (context, ask_pass, ask_pass_data,
+		         pass_not_needed, pass_not_needed_data,
+		         exit_status, error);
+}
+
+/**
+ * gksu_run
+ * @command_line: the command line that will be executed as other user
+ * @error: a #GError to be set with the error condition, if an error
+ * happens
+ *
+ * This function is a wrapper for gksu_sudo/gksu_su. It will call one
+ * of them, depending on the GConf key that defines whether the default
+ * behavior for gksu is su or sudo mode. This is the recommended way of
+ * using the library functionality.
+ *
+ * Returns: FALSE if all went well, TRUE if an error happend.
+ */
+gboolean
+gksu_run (gchar *command_line,
+	  GError **error)
+{
+  GConfClient *gconf_client;
+  gboolean sudo_mode;
+
+  gconf_client = gconf_client_get_default ();
+  sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
+				     NULL);
+  g_object_unref (gconf_client);
+
+  if (sudo_mode)
+    return gksu_sudo (command_line, error);
+
+  return gksu_su (command_line, error);
+}
+
+/**
+ * gksu_ask_password_full:
+ * @context: a #GksuContext
+ * @prompt: a prompt different from Password:
+ * @error: a #GError object to be filled with the error code or NULL
+ *
+ * This function uses the gksu infra-structure to request for a
+ * password, but instead of passing it to su or sudo to run a command
+ * it simply returns the password.
+ *
+ * Returns: a newly allocated string with the password;
+ */
+gchar*
+gksu_ask_password_full (GksuContext *context, gchar *prompt,
+			GError **error)
+{
+  gchar *ret_value = su_ask_password (context, _(prompt), NULL, error);
+  if (context->sn_context)
+    gksu_context_launch_complete (context);
+  return ret_value;
+}
+
+/**
+ * gksu_ask_password
+ * @error: a #GError to be set with the error condition, if an error
+ * happens
+ *
+ * This function uses the gksu infra-structure to request for a
+ * password, but instead of passing it to su or sudo to run a command
+ * it simply returns the password. This is just a convenience wrapper
+ * for gksu_ask_password_full.
+ *
+ * Returns: a newly allocated string with the password;
+ */
+gchar*
+gksu_ask_password (GError **error)
+{
+  GksuContext *context = gksu_context_new ();
+  gchar* retval;
+
+  context->user = g_strdup ("root");
+  retval = gksu_ask_password_full (context, NULL, error);
+  gksu_context_free (context);
+
+  return retval;
+}




More information about the gksu-commits mailing list