#! /bin/sh
#
# Script to activate profiles (i.e. conditional extra stuff) for the various 
# desktop environments in Debian based on the data in the *.listing files in
# the /etc/desktop-profiles directory. Sourced by /etc/X11/Xsession.
#
# See the desktop-profiles(7) man page for an overview of how this works
#
# Code in this file has a couple of debian-specific parts:
#  - use of tempfile from debian-utils
#  - hardcoded default values for the different GNUSTEP_*_ROOT env variables
#
# (c) 2004-2005 Bart Cornelis <cobaco AT skolelinux no>
###############################################################################

########################################################
# get utility functions for working with .listing files
########################################################
LIB=/usr/share/desktop-profiles/listingmodule;
if (test -r $LIB); then
  . $LIB;
  INSTALLED=true;
else
  # test for shell-library if absent then either:
  # - the package installation is corrupt
  # - the pacakge is removed (this file is left as it's in /etc/ and
  #   thus treated as a conffile
  # We'll assume the latter.
  echo "Shell library $LIB is missing -> assuming desktop-profiles is removed (but not purged)" >> $ERRFILE;
  INSTALLED=false
fi;

#########################################################################
# Sort all profiles that have their requirements met by kind
# (result for each $KIND are saved in the file pointed to by $KIND_FILE)
#########################################################################
sort_profiles(){

  #make sure we start with empty variables
  KDEDIRS='';XDG_CONFIG_DIRS='';XDG_DATA_DIRS='';CHOICESPATH='';GNUSTEP_PATHLIST='';UDEDIRS=''
 
  # get profiles that are have fulfilled requirements, and save result on file descriptor 3
  PROFILES=`tempfile`;
  exec 3<> $PROFILES;
  (# get profiles that are have fulfilled requirements
     cat $(list_listings) | grep -v -e "^[[:space:]]*#" -e "^[[:space:]]*$" | while read PROFILE; do
      if (test_profile_requirements "$PROFILE"); then
        echo $PROFILE;
      fi;
    done;
   #and sort them by preference 
  ) | sort --reverse --general-numeric-sort --field-separator=";" --key 4 > $PROFILES;

  # read from file descriptor 3 (not using pipe, because then the variables being
  # changed are in a subshell, which means they're unchanged outside the while loop)
  while read PROFILE <&3; do
  # sort per profile kind
    KIND=`echo "$PROFILE" | cut --fields 2 --delimiter ";"`;
    if (test "$KIND" = "KDE"); then 
      KDEDIRS="$KDEDIRS $(echo "$PROFILE" | cut --fields 3 --delimiter ";")";
    elif (test "$KIND" = "XDG_CONFIG"); then 
      XDG_CONFIG_DIRS="$XDG_CONFIG_DIRS $(echo "$PROFILE" | cut --fields 3 --delimiter ";")";
    elif (test "$KIND" = "XDG_DATA"); then 
      XDG_DATA_DIRS="$XDG_DATA_DIRS $(echo "$PROFILE" | cut --fields 3 --delimiter ";")";
    elif (test "$KIND" = "ROX"); then 
      CHOICESPATH="$CHOICESPATH $(echo "$PROFILE" | cut --fields 3 --delimiter ";")";
    elif (test "$KIND" = "GNUSTEP"); then 
      GNUSTEP_PATHLIST="$GNUSTEP_PATHLIST $(echo "$PROFILE" | cut --fields 3 --delimiter ";")";
    elif (test "$KIND" = "UDE"); then 
      UDEDIRS="$UDEDIRS $(echo "$PROFILE" | cut --fields 3 --delimiter ";")";
    elif (test "$KIND" = "GCONF"); then 
      echo "`echo "$PROFILE" | cut --fields 3 --delimiter ";"` " >> $GCONF_FILE;
    fi;	
  done;

  # close filedescriptor,and delete tempfile
  exec 3>&- ; 
  rm $PROFILES;
}

##########################################################
# Functions for activating the different kinds of profile
##########################################################
activate_KDE () {
  KDEDIRS=`echo "$KDEDIRS" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"`
  if (test "$KDEDIRS"x != x) &&
     (test "$KDEDIRS" != "`cat $DEFAULT_LISTING | grep "^kde-prefix" | cut --fields 3 --delimiter ";" | sed -e  "s/^ *//" -e "s/ *$//" -e "s/ /:/g"`"); then
    KDEDIRS=$(sh -c "echo $KDEDIRS");# FORCE expansion of variables in KDEDIRS if any
    export KDEDIRS;
  fi;
}

activate_XDG_CONFIG () {
  XDG_CONFIG_DIRS=`echo "$XDG_CONFIG_DIRS" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"`
  if (test "$XDG_CONFIG_DIRS"x != x) &&
     (test "$XDG_CONFIG_DIRS" != "`cat $DEFAULT_LISTING | grep "^default-xdg_config_dirs" | cut --fields 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"`"); then
    XDG_CONFIG_DIRS=$(sh -c "echo $XDG_CONFIG_DIRS");# FORCE expansion of variables in XDG_CONFIG_DIRS if any
    export XDG_CONFIG_DIRS;
  fi;
}

activate_XDG_DATA () {
  XDG_DATA_DIRS=`echo "$XDG_DATA_DIRS" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"`
  if (test "$XDG_DATA_DIRS"x != x) &&
     (test "$XDG_DATA_DIRS" != "`cat $DEFAULT_LISTING | grep "^default-xdg_data_dirs" | cut --fields 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"`"); then
    XDG_DATA_DIRS=$(sh -c "echo $XDG_DATA_DIRS");# FORCE expansion of variables in XDG_DATA_DIRS if any
    export XDG_DATA_DIRS;
  fi;
}

activate_ROX () {
  CHOICESPATH=`echo "$CHOICESPATH" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"`
  DEFAULT_CHOICES=$(cat $DEFAULT_LISTING | grep '^default-rox-system;' | cut --field 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g")
  DEFAULT_CHOICES="$(cat $DEFAULT_LISTING | grep '^default-rox-user;' | cut --field 3 --delimiter ";" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"):$DEFAULT_CHOICES"
  if (test "$CHOICESPATH"x != x) &&
     (test "$CHOICESPATH" != "$DEFAULT_CHOICES"); then
    CHOICESPATH=$(sh -c "echo $CHOICESPATH");# FORCE expansion of variables in CHOICESPATH if any
    export CHOICESPATH;
  fi;
}

activate_UDE () {
  # don't s/ /:g/ in next line, UDE doesn't currently support combining profile dirs
  UDEDIRS=`echo "$UDEDIRS" | sed -e "s/^ *//" -e "s/ *$//"`
  if (test "$UDEDIRS"x != x) &&
     (test "$UDEDIRS" != "`cat $DEFAULT_LISTING | grep "^ude-install-dir" | cut --fields 3 --delimiter ";"`"); then
    # Take first dir and break, as UDE currently only supports one dir
    for dir in $UDEDIRS; do 
      UDEdir=$dir;
      break;
    done;  
    export UDEdir=$(sh -c "echo $UDEdir");# FORCE expansion of variables in UDEdir if any
  fi;
}

activate_GNUSTEP () {
  # default values as set in /usr/lib/GNUstep/System/Library/Makefiles/GNUstep.sh (On Debian)
  export GNUSTEP_USER_ROOT=${GNUSTEP_USER_ROOT:-`/usr/lib/GNUstep/System/Library/Makefiles/user_home user`};
  export GNUSTEP_LOCAL_ROOT=${GNUSTEP_LOCAL_ROOT:-/usr/local/lib/GNUstep/Local};
  export GNUSTEP_NETWORK_ROOT=${GNUSTEP_NETWORK_ROOT:-/usr/local/lib/GNUstep/Network};
  export GNUSTEP_SYSTEM_ROOT=${GNUSTEP_SYSTEM_ROOT:-/usr/lib/GNUstep/System};

  #should be in GNUSTEP_PATHLIST (see /usr/lib/GNUstep/System/Library/Makefiles/GNUstep.sh)
  GNUSTEP_PATHLIST=`echo "$GNUSTEP_PATHLIST" | sed -e "s/^ *//" -e "s/ *$//" -e "s/ /:/g"`
  
  # get default domains
  DEFAULT_DOMAINS=$(cat $DEFAULT_LISTING | grep "^gnustep-user-domain" | cut --fields 3 --delimiter ";" | sed -e  "s/^ *//" -e "s/ *$//" -e "s/ /:/g")
  DEFAULT_DOMAINS="$DEFAULT_DOMAINS:$(cat $DEFAULT_LISTING | grep "^gnustep-local-domain" | cut --fields 3 --delimiter ";" | sed -e  "s/^ *//" -e "s/ *$//" -e "s/ /:/g")"
  DEFAULT_DOMAINS="$DEFAULT_DOMAINS:$(cat $DEFAULT_LISTING | grep "^gnustep-network-domain" | cut --fields 3 --delimiter ";" | sed -e  "s/^ *//" -e "s/ *$//" -e "s/ /:/g")"
  DEFAULT_DOMAINS="$DEFAULT_DOMAINS:$(cat $DEFAULT_LISTING | grep "^gnustep-system-domain" | cut --fields 3 --delimiter ";" | sed -e  "s/^ *//" -e "s/ *$//" -e "s/ /:/g")"

  if (test "$GNUSTEP_PATHLIST"x != x) &&
     (test "$GNUSTEP_PATHLIST" != "$DEFAULT_DOMAINS"); then
    export GNUSTEP_PATHLIST=$(sh -c "echo $GNUSTEP_PATHLIST");# FORCE expansion of variables in GNUSTEP_PATHLIST if any
  else
    # if we're not setting things, then make sure we've not added to the environment
    if (test "$GNUSTEP_USER_ROOT" = "$(/usr/lib/GNUstep/System/Library/Makefiles/user_home user)"); then unset GNUSTEP_USER_ROOT; fi
    if (test "$GNUSTEP_LOCAL_ROOT" = "/usr/local/lib/GNUstep/Local"); then unset GNUSTEP_LOCAL_ROOT; fi
    if (test "$GNUSTEP_NETWORK_ROOT" = "/usr/local/lib/GNUstep/Network"); then unset GNUSTEP_NETWORK_ROOT; fi
    if (test "$GNUSTEP_SYSTEM_ROOT" = "/usr/lib/GNUstep/System"); then unset GNUSTEP_SYSTEM_ROOT; fi
  fi;
}

activate_GCONF () {
  # HACK WARNING:
  #
  # While GCONF allows multiple "configuration sources", there seems to be no clean way to
  # make the used "configuration sources" dependend on a condition (such as group membership).
  # One dirty way to get this ability is to generate a path file at login which will include
  # directives activating the profiles that have their requirements met.
  #
  # NOTE: this alone isn't enough, the system-wide path file (/etc/gconf/<gconf-version>/path)
  #       needs to contain a include directive for this generated file. (preferably it should 
  #       contain _only_ that include directive setting everything else up through profiles)
  
  # only generate path files for user if it will be included
  if (grep '/var/cache/desktop-profiles/\$(USER)_mandatory.path' /etc/gconf/2/path 2>&1 > /dev/null ) ||
     (grep '/var/cache/desktop-profiles/\$(USER)_defaults.path'  /etc/gconf/2/path 2>&1 > /dev/null ) ||
     (grep '/var/cache/desktop-profiles/\$(USER)_mandatory.path' /etc/gconf/1/path 2>&1 > /dev/null ) ||
     (grep '/var/cache/desktop-profiles/\$(USER)_defaults.path'  /etc/gconf/1/path 2>&1 > /dev/null ); then

    INCLUDED_HOME=false; 
    echo "# Generated by desktop-profiles package" > "$PROFILE_PATH_FILES_DIR/${USER}_mandatory.path";
    echo "# Generated by desktop-profiles package" > "$PROFILE_PATH_FILES_DIR/${USER}_defaults.path";
    
    cat $GCONF_FILE | while read LINE; do
       if (test "$LINE" != 'xml:readwrite:$(HOME)/.gconf'); then
         if (test $INCLUDED_HOME = false); then
           echo $LINE >> "$PROFILE_PATH_FILES_DIR/${USER}_mandatory.path";
         else	 
           echo $LINE >> "$PROFILE_PATH_FILES_DIR/${USER}_defaults.path";
         fi;	 
       else  
         INCLUDED_HOME=true;
       fi  
    done;
  fi;  
}

#####################
# Start of execution
#####################
if (test $INSTALLED = true); then
  #################################
  # Check if user set any defaults
  #################################
  if (test -r /etc/default/desktop-profiles); then
    . /etc/default/desktop-profiles;
  fi;  

  #################################################
  # Make sure the variable we need are initialized
  #################################################
  LISTINGS_DIRS=${LISTINGS_DIRS:-'/etc/desktop-profiles'}
  ACTIVE_PROFILE_KINDS=${ACTIVE_PROFILE_KINDS:-''}
  DEFAULT_LISTING=/etc/desktop-profiles/desktop-profiles.listing
  PROFILE_PATH_FILES_DIR=${PROFILE_PATH_FILES_DIR:-'/var/cache/desktop-profiles/'}

  ############################################################
  # Actual activation of profiles
  # don't test requirements if no profile kinds are activated
  ############################################################
  if (test "$ACTIVE_PROFILE_KINDS"x != "x"); then
    # get temp file names
    GCONF_FILE=`tempfile`;

    # sort the profile into the temp files
    sort_profiles; 

    # activate the profiles of the active kinds
    for KIND in $ACTIVE_PROFILE_KINDS; do
      # || true is to avoid hanging x-startup when trying a non-existing KIND
      # which can happen e.g. due to typo's in the config file.
      activate_$KIND || true;
    done;

    # cleanup the tempfiles
    rm $GCONF_FILE 
  fi;  
fi;  
