Bug#648220: Re-implementing use of $HOME/.dmrc

Paul Szabo paul.szabo at sydney.edu.au
Thu Sep 20 03:56:23 UTC 2012


While testing wheezy, I noticed that ~/.dmrc is not used anymore; and
that my selection of session was not remembered. (I did not have any
success with the suggestion in comment#20.) I need session selection
in ~/.dmrc, so users get the same session on any of our servers that
share home directories via NFS.
 
I re-implemented the session selection functionality of ~/.dmrc by
adding a couple of lines of code to /etc/gdm3/Xsession (attached).

Cheers, Paul

Paul Szabo   psz at maths.usyd.edu.au   http://www.maths.usyd.edu.au/u/psz/
School of Mathematics and Statistics   University of Sydney    Australia
-------------- next part --------------
#!/bin/bash
# PSz 26 Jun 2012  Above was /bin/sh but should be bash,
# as that is the shell we custimize with PATH, PRINTER etc,
# and we want to get environment right for all children.

# This is SORT OF LIKE an X session, but not quite.  You get a command as the
# first argument (it could be multiple words, so run it with "eval").  As a
# special case, the command can be:
#  failsafe - Run an xterm only
#  default - Run the appropriate Xclients startup (see the code below)
#  custom - Run ~/.xsession and if that's not available run 'default'
#
# (Note that other arguments could also follow, but only the command one is
# right now relevant and supported)
#
# The output is ALREADY redirected to .xsession-errors in GDM.  This way
# .xsession-errors actually gets more output such as if the PreSession script
# is failing.  This also prevents DoS attacks if some app in the users session
# can be prodded to dump lots of stuff on the stdout/stderr.  We wish to be
# robust don't we?  In case you wish to use an existing script for other DM's,
# you can just not redirect when GDMSESSION is set.  GDMSESSION will always
# be set from gdm.
#
# Also note that this is not run as a login shell, this is just executed.
#
# based on:
# $XConsortium: Xsession /main/10 1995/12/18 18:21:28 gildea $

PROGNAME=Xsession

message () {
  # pretty-print messages of arbitrary length; use xmessage if it
  # is available and $DISPLAY is set
  MESSAGE="$PROGNAME: $*"
  echo "$MESSAGE" | fold -s -w ${COLUMNS:-80} >&2
  if [ -n "$DISPLAY" ]; then
    if [ -n "$zenity" ]; then
      "$zenity" --info --text "$MESSAGE"
    elif [ -n "$xmessage" ]; then
      echo "$MESSAGE" | fold -s -w ${COLUMNS:-80} | $xmessage -center -file -
    fi
  fi
}

message_nonl () {
  # pretty-print messages of arbitrary length (no trailing newline); use
  # xmessage if it is available and $DISPLAY is set
  MESSAGE="$PROGNAME: $*"
  echo -n "$MESSAGE" | fold -s -w ${COLUMNS:-80} >&2;
  if [ -n "$DISPLAY" ]; then
    if [ -n "$zenity" ]; then
      "$zenity" --info --text "$MESSAGE"
    elif [ -n "$xmessage" ]; then
      echo -n "$MESSAGE" | fold -s -w ${COLUMNS:-80} | $xmessage -center -file -
    fi
  fi
}

errormsg () {
  # exit script with error
  message "$*"
  exit 1
}

internal_errormsg () {
  # exit script with error; essentially a "THIS SHOULD NEVER HAPPEN" message
  # One big call to message() for the sake of xmessage; if we had two then
  # the user would have dismissed the error we want reported before seeing the
  # request to report it.
  errormsg "$*" \
           "Please report the installed version of the \"xfree86-common\"" \
           "package and the complete text of this error message to" \
           "<debian-x at lists.debian.org>."
}

run_parts () {
  # until run-parts --noexec is implemented
  if [ -z "$1" ]; then
    internal_errormsg "run_parts() called without an argument."
  fi
  if [ ! -d "$1" ]; then
    internal_errormsg "run_parts() called, but \"$1\" does not exist or is" \
                      "not a directory."
  fi
  for F in $(/bin/ls $1); do
    if expr "$F" : '[[:alnum:]_-]\+$' > /dev/null 2>&1; then
      if [ -f "$1/$F" ]; then
        echo "$1/$F"
      fi
    fi
  done
}
# initialize variables for use by all session scripts

OPTIONFILE=/etc/X11/Xsession.options

SYSRESOURCES=/etc/X11/Xresources
USRRESOURCES=$HOME/.Xresources

SYSSESSIONDIR=/etc/X11/Xsession.d
USERXSESSION=$HOME/.xsession
USERXSESSIONRC=$HOME/.xsessionrc
ALTUSERXSESSION=$HOME/.Xsession

# this will go into the .xsession-errors along with all other echo's
# good for debugging where things went wrong
echo "$0: Beginning session setup for $1 ..."

# First read /etc/profile and .profile
test -f /etc/profile && . /etc/profile
test -f "$HOME/.profile" && . "$HOME/.profile"
# Second read /etc/xprofile and .xprofile for X specific setup
test -f /etc/xprofile && . /etc/xprofile
test -f "$HOME/.xprofile" && . "$HOME/.xprofile"

zenity=`which zenity 2>/dev/null`
xmessage=`which xmessage 2>/dev/null`

command="$1"

if [ -z "$command" ] ; then
  command=failsafe
fi

if [ x"$command" = xfailsafe ] ; then
  if [ -n "$zenity" ] ; then
    "$zenity" --info --text "This is the failsafe xterm session.  Windows now have focus only if you have your cursor above them.  To get out of this mode type 'exit' in the window in the upper left corner"
  else
    echo "$0: Starting the failsafe xterm session."
  fi
  exec xterm -geometry 80x24+0+0
fi

# clean up after xbanner
freetemp=`which freetemp 2>/dev/null`
if [ -n "$freetemp" ] ; then
        "$freetemp"
fi

usermodmap="$HOME/.Xmodmap"
userxkbmap="$HOME/.Xkbmap"

if [ -f "$userxkbmap" ]; then
    setxkbmap `cat "$userxkbmap"`
    XKB_IN_USE=yes
fi

# xkb and xmodmap don't play nice together
if [ -z "$XKB_IN_USE" ]; then
    if [ -f "$usermodmap" ]; then
       xmodmap "$usermodmap"
    fi
fi

unset XKB_IN_USE

if [ -n "$GDM_LANG" ]; then
    # Set the locale to that, it's the language selected in GDM.
    LANG="$GDM_LANG"
    export LANG

    if [ -n "$LC_ALL" ] && [ "$LC_ALL" != "$LANG" ]; then
        LC_ALL="$LANG"
    fi

    # if GDM_LANG isn't first in LANGUAGE, then unset it.
    if [ -n "$LANGUAGE" ]; then
        if echo "$LANGUAGE" | grep -q -- "^$GDM_LANG"; then
           :
        else
           unset LANGUAGE
        fi
    fi
fi

# The default Debian session runs xsession first, so we just do that for
# "custom"
if [ "x$command" = "xcustom" ] ; then
  shift
  set default $*
fi

# PSz 20 Sep 2012  Poor man's handling of ~/.dmrc
# Though it still is documented to use ~/.dmrc:
#   http://library.gnome.org/admin/gdm/stable/configuration.html.en#userconfig
# it is a "known bug" that GDM does not use it anymore:
#   http://lxnay.wordpress.com/2011/09/13/yet-another-gnomegdm-3-idiocy-dropping-dmrc-support/
#   https://bugzilla.gnome.org/show_bug.cgi?id=594733
#   Source gdm-3.4.1/NEWS:- Move from ~/.dmrc to accounts service
# Debian and others are left out in the cold:
#   https://bugzilla.redhat.com/show_bug.cgi?id=617465
#   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=638353
#   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=648220
# Use xdm instead? But xdm does not use ~/.dmrc either.
# Use lightdm maybe? Has issues, and does not work:
#   https://bugs.launchpad.net/lightdm/+bug/837002
#   https://bugs.launchpad.net/lightdm-gtk-greeter/+bug/1031421
# Thus I decided to re-implement the functionality,
# for the "Session" selection. I do not care about "Language" (yet).
case "$1" in
  '' )
    # Could this ever happen? Do not know what to do...
  ;;
  default )
    # User chose "system default" session, which is default.
    # See if user has something more sensible in ~/.dmrc already.
    # I like perl, could use sed or "shell functions", instead.
    if [ -f $HOME/.dmrc ]; then
      dmrc=$(perl -ne 's/^\s*Session\s*=\s*([a-zA-Z0-9\/-]+)\s*$/$1/ and print,exit' $HOME/.dmrc)
      if [ -n "$dmrc" ]; then
        echo "$0: Using Session=$dmrc from ~/.dmrc instead of default"
        shift
        set $dmrc $*
      fi
    fi
  ;;
  * )
    # Got some (non-trivial?) session selection, record it in ~/.dmrc
    # in standard format
    echo -e "[Desktop]\nSession=$1" > $HOME/.dmrc
    echo "$0: Recorded Session=$1 in ~/.dmrc"
  ;;
esac

# use run-parts to source every file in the session directory; we source
# instead of executing so that the variables and functions defined above
# are available to the scripts, and so that they can pass variables to each
# other
SESSIONFILES=$(run_parts $SYSSESSIONDIR)
if [ -n "$SESSIONFILES" ]; then
  for SESSIONFILE in $SESSIONFILES; do
    . $SESSIONFILE
  done
fi

echo "$0: Executing $command failed, will try to run x-terminal-emulator"

if [ -n "$zenity" ] ; then
        "$zenity" --info --text "I could not start your session and so I have started the failsafe xterm session.  Windows now have focus only if you have your cursor above them.  To get out of this mode type 'exit' in the window in the upper left corner"
fi

exec x-terminal-emulator -geometry 80x24+0+0


More information about the pkg-gnome-maintainers mailing list