#!/bin/sh
#
# Copyright 2002-2004 by Roland Mainz <roland.mainz@nrubsig.org>.
#
# This script manages the Xprint server side

# Basic support for IRIX-style "chkconfig"
# chkconfig: 2345 61 61
# description: Startup/shutdown script for Xprint server(s)

# Basic support for the Linux Standard Base Specification 1.0.0
# (Note: The Should-Start/Stop lines are there so that this works in the
# future, when the LSB adopts these. The X-UnitedLinux lines are there 
# so that it works right now.)
### BEGIN INIT INFO
# Provides: xprint
# Required-Start: $local_fs $remote_fs $syslog $network
# Required-Stop: $local_fs $remote_fs $syslog
# Should-Start: cups lpd xfs
# Should-Stop:  cups lpd xfs
# X-UnitedLinux-Should-Start: cups lpd xfs
# X-UnitedLinux-Should-Stop:  cups lpd xfs
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: Startup/shutdown script for Xprint server(s)
### END INIT INFO




############################################################################
#
# This script has three main tasks:
# 1. Start Xprint servers ("Xprt") at boot time.
# 2. Shutdown Xprint servers when the machine is being shut down.
# 3. Query the list of available printers.
#
# Additional tasks are:
# 4. Restart ('restart'|'force-reload') and conditional restart
#    ('condrestart'/'try-restart') for Linux support
# 5. Wrapping of application call with setting XPSERVERLIST ('wrapper')
#
# Usage:
# - Start Xprint server(s) manually:
#   % /etc/init.d/xprint start
#
# - Stop Xprint server(s) manually:
#   % /etc/init.d/xprint stop
#
# - Populate $XPSERVERLIST env var (for example as part of a global
#   login script like /etc/profile or per-user login scripts like
#   $HOME/.profile (sh/ksh/bash))
#   % XPSERVERLIST="`/etc/init.d/xprint get_xpserverlist`"
#   % export XPSERVERLIST
#
# Installation:
#   Copy this script to /etc/init.d/xprint and make sure that it is
#   executable. If your installation is LSB-compliant, then run
#   % /usr/lib/lsb/install_initd /etc/init.d/xprint
#   to start the service on startup. Otherwise, manually create links
#   to the matching run levels.
#   Examples:
#     - Solaris 2.7/2.8/2.9:
#       % cp xprint /etc/init.d/xprint
#       % chmod a+rx /etc/init.d/xprint
#       % ln /etc/init.d/xprint /etc/rc0.d/K38xprint
#       % ln /etc/init.d/xprint /etc/rc1.d/K38xprint
#       % ln /etc/init.d/xprint /etc/rc2.d/S81xprint
#       % ln /etc/init.d/xprint /etc/rcS.d/K38xprint
#
#     - SuSE Linux 7.3
#       % cp xprint /etc/init.d/xprint
#       % chmod a+rx /etc/init.d/xprint
#       % ln -s ../xprint /etc/init.d/rc3.d/K13xprint
#       % ln -s ../xprint /etc/init.d/rc3.d/S12xprint
#       % ln -s ../xprint /etc/init.d/rc5.d/K13xprint
#       % ln -s ../xprint /etc/init.d/rc5.d/S12xprint
#       % ln -s ../xprint /etc/init.d/rc2.d/K13xprint
#       % ln -s ../xprint /etc/init.d/rc2.d/S12xprint
#
#     - SuSE Linux 6.4:
#       % cp xprint /sbin/init.d/xprint
#       % chmod a+rx /sbin/init.d/xprint
#       % ln -s ../xprint /sbin/init.d/rc2.d/K20xprint
#       % ln -s ../xprint /sbin/init.d/rc2.d/S20xprint
#       % ln -s ../xprint /sbin/init.d/rc3.d/K20xprint
#       % ln -s ../xprint /sbin/init.d/rc3.d/S20xprint
#
#   Notes: 
#   - The Xprint servers must be started _after_ the print
#     spooler or the server(s) may refuse to start
#   - The script should be readable by all users to ensure that they
#     can use the "get_xpserverlist"-option
#
# Custom configuration:
#   - Edit the function setup_config() in this script to match your needs
#
# Known bugs/ToDo/Notes:
#   - The shell script assumes that a Xserver can be reached via 
#     "hostname:displaynum" where "hostname" is obtained from
#     "/usr/bin/hostname". It may happen that a kernel firewall
#     blocks an X connection on the same host (e.g. client && Xserver 
#     are running on the same host).
#     Suggested fix: Fix the firewall config.
#     Suggested workaround: Edit this script and replace the use of 
#     /usr/bin/hostname with "echo 'localhost'".
#
############################################################################
#


############################################################################

fatal_error()
{
    echo "${0}: ## FATAL ERROR: ${1}" 1>&2
    exit 1
}

error_echo()
{
    echo "${0}: ## ERROR: ${1}" 1>&2
}

warning_echo()
{
    echo "${0}: ## WARNING: ${1}" 1>&2
}

verbose_echo()
{
    echo "${0}: ${1}"
}

msg()
{
    echo "${1}"
}

############################################################################


# Force use of a POSIX conformant sh 
# (Solaris /sbin/sh is plain Bourne shell)
[ "$1" != "posix_sh_forced" -a -x /bin/ksh  ]            && exec /bin/ksh  "$0" posix_sh_forced "$@"
[ "$1" != "posix_sh_forced" -a -x /bin/bash ]            && exec /bin/bash --norc --noprofile "$0" posix_sh_forced "$@"
[ "$1" != "posix_sh_forced" -a -x /usr/local/bin/ksh ]   && exec /usr/local/bin/ksh "$0" posix_sh_forced "$@"
[ "$1" != "posix_sh_forced" -a -x /usr/local/bin/bash ]  && exec /usr/local/bin/bash --norc --noprofile "$0" posix_sh_forced "$@"
if [ "$1" != "posix_sh_forced" ] ; then
    echo "${0}: ## FATAL ERROR: No POSIX-shell found."  1>&2
    exit 1
fi

shift # Drop "posix_sh_forced"


##debug
# set -x

# Change current dir to a location which is writeable by everyone
cd /tmp

# Clear some environment variables
unset TEMP TMPDIR SCREENDIR

# Set search path for commands
export PATH=/usr/bin:/bin:/usr/sbin:/sbin




## Try to figure-out where X11 was installed







[ -d /usr/X11R6/bin ]	&& XPROJECTROOT=/usr/X11R6

[ -d /usr/X11/bin ]     && XPROJECTROOT=/usr/X11
[ -d /usr/X11R6/bin ]   && XPROJECTROOT=/usr/X11R6

XPCUSTOMGLUE=default # This is used for customizing this script
export XPROJECTROOT XPCUSTOMGLUE

if [ -z "${XPROJECTROOT}" ] ; then
    fatal_error "Unknown XProjectRoot."
fi

# Set the location of the Xprt binary we want to use.
XPRT_BIN="${XPROJECTROOT}/bin/Xprt"

# Set the location of the global file where we store the locations 
# of the system-wide servers
if [ -d /var/run ] ; then
    XP_GLOBAL_SERVERS=/var/run/Xprint_servers
else
    XP_GLOBAL_SERVERS=/tmp/.Xprint_servers
fi

# ${LOGNAME} will not work if user su'ed into another account
export CURRLOGNAME="$(id -u -n)"

# Set location where we want to store the list of Xprint servers managed
# by this user
# - If we start as "root" use the global file
# - If we start as normal user use a per-user file

if [ "${CURRLOGNAME}" != "root" -a "${CURRLOGNAME}" != "" ] ; then
    XP_PER_USER_SERVERS="/tmp/.Xprint_servers_${CURRLOGNAME}"
    XP_SERVERS="${XP_PER_USER_SERVERS}"
else
    XP_SERVERS="${XP_GLOBAL_SERVERS}"
fi

# Set umask that owner can r/w all files and everyone else can read them
umask 022

# Bump limit for per-process open files to ensure that Xprt can open many many fonts
ulimit -n 1024

############################################################################

# Get list of fonts for a given display
get_fontlist_from_display()
{
    ${XPROJECTROOT}/bin/xset -display "${1}" q | 
      awk "/Font Path:/ { i=1 ; next } i==1 { print \$0 ; i=0 }" | 
        fontpath2fontlist
}

# Get list from a fontserver config
get_fontlist_from_xfs_config()
{
    if [ ! -r "${1}" ] ; then
        return 0
    fi
      
    (        
      cat "${1}" |
      while read -r i ; do
          for val in $i; do
              case $val in
                \#*)  break ;;
                ?*=*) key="${val%%=*}" ;;
                =*)   key="${tok}" ;;
                *)    [ "${key}" = "catalogue" -a "${tok}" != "" ] && echo "${tok}" ;;
              esac
              tok="${val#*=}"
          done
      done
    ) | tr "," "\n" | fontpath2fontlist
}

get_fontlist_from_all_xfs_configs()
{
    get_fontlist_from_xfs_config "/etc/openwin/fs/fontserver.cfg"
    get_fontlist_from_xfs_config "/usr/openwin/lib/X11/fontserver.cfg"
    get_fontlist_from_xfs_config "/etc/X11/fs-xtt/config"
    get_fontlist_from_xfs_config "/etc/X11/fs/config"
    get_fontlist_from_xfs_config "/etc/X11/xfs/config"
    get_fontlist_from_xfs_config "${XPROJECTROOT}/lib/X11/fs/config"
}

get_fontlist_from_xf86config()
{
    srcxconf=""

    # see xorg.conf(5x) manual page for the list of locations used here    
    [ "${srcxconf}" = "" -a -f "/etc/X11/xorg.conf"  ]                      && srcxconf="/etc/X11/xorg.conf"
    [ "${srcxconf}" = "" -a -f "/usr/X11R6/etc/X11/xorg.conf" ]             && srcxconf="/usr/X11R6/etc/X11/xorg.conf"
    [ "${srcxconf}" = "" -a -f "/etc/X11/xorg.conf-4" ]                     && srcxconf="/etc/X11/xorg.conf-4"
    [ "${srcxconf}" = "" -a -f "/etc/X11/xorg.conf" ]                       && srcxconf="/etc/X11/xorg.conf"
    [ "${srcxconf}" = "" -a -f "/etc/xorg.conf" ]                           && srcxconf="/etc/xorg.conf"
    [ "${srcxconf}" = "" -a -f "/usr/X11R6/etc/X11/xorg.conf.${hostname}" ] && srcxconf="/usr/X11R6/etc/X11/xorg.conf.${hostname}"
    [ "${srcxconf}" = "" -a -f "/usr/X11R6/etc/X11/xorg.conf-4" ]           && srcxconf="/usr/X11R6/etc/X11/xorg.conf-4"
    [ "${srcxconf}" = "" -a -f "/usr/X11R6/etc/X11/xorg.conf" ]             && srcxconf="/usr/X11R6/etc/X11/xorg.conf"
    [ "${srcxconf}" = "" -a -f "/usr/X11R6/lib/X11/xorg.conf.${hostname}" ] && srcxconf="/usr/X11R6/lib/X11/xorg.conf.${hostname}"
    [ "${srcxconf}" = "" -a -f "/usr/X11R6/lib/X11/xorg.conf-4" ]           && srcxconf="/usr/X11R6/lib/X11/xorg.conf-4"
    [ "${srcxconf}" = "" -a -f "/usr/X11R6/lib/X11/xorg.conf" ]             && srcxconf="/usr/X11R6/lib/X11/xorg.conf"

    # Xfree86 locations
    [ "${srcxconf}" = "" -a -f "/etc/X11/XF86Config-4" ] && srcxconf="/etc/X11/XF86Config-4"
    [ "${srcxconf}" = "" -a -f "/etc/X11/XF86Config" ]   && srcxconf="/etc/X11/XF86Config"


    if [ "${srcxconf}" = "" ] ; then
        return 0
    fi

    currsection=""
    cat "${srcxconf}" |
    while read i1 i2 i3 i4 ; do
        # Strip "\"" from I2
        i2="${i2#\"}" ; i2="${i2%\"}"

        case "${i1}" in
            \#*)
                continue
                ;;
            'Section')
                currsection="${i2}"
                ;;
            'EndSection')
                currsection=""
                ;;
            'FontPath')
                [ "$currsection" = "Files" ] && echo "${i2%:unscaled}"
                ;;
        esac  
    done | egrep -v -i "tcp/|tcp4/|tcp6/|unix/"
    
    return 0
}

get_fontlist_from_defoma()
{
    # Include Debian defoma font directory where relevant
    if [ -d "/var/lib/defoma/x-ttcidfont-conf.d/dirs" ] ; then        
        find "/var/lib/defoma/x-ttcidfont-conf.d/dirs" -name fonts.dir |
          while read i ; do echo "${i%/fonts.dir}" ; done
    fi
}

# Get list of system fonts
get_system_fontlist()
{
          ## List the standard X11 fonts
          # (AIX should be handled like Solaris but I did not found a way to
          # enumerate all fonts in all installed locales without scanning the
          # dirs manually)
          echo "${XPROJECTROOT}/lib/X11/fonts/Type1/"
          echo "${XPROJECTROOT}/lib/X11/fonts/TrueType/"
          echo "${XPROJECTROOT}/lib/X11/fonts/TTF/"
          echo "${XPROJECTROOT}/lib/X11/fonts/Speedo/"
          echo "${XPROJECTROOT}/lib/X11/fonts/misc/"
          echo "${XPROJECTROOT}/lib/X11/fonts/75dpi/"
          echo "${XPROJECTROOT}/lib/X11/fonts/100dpi/"
          echo "${XPROJECTROOT}/lib/X11/fonts/"

}

# Filter fonts per given extended regular expressions
# (and make sure we filter any model-config fonts - they are managed by Xprt internally)
filter_fontlist()
{
    egrep -- "${1}" | fgrep -v "/models/" | egrep -v -- "${2}"
}

# Filter font paths with unsupported font types
# (such as CID fonts)
filter_unsupported_fonts()
{
    egrep -v -i "/cid(/$|$)|/csl(/$|$)"
}

# Validate fontpath
# Only return valid font path entries (note that these entries may
# include non-file stuff like font server references)
validate_fontlist()
{
    while read i ; do       
        case "${i}" in
            # Check if font path entry is a font server...
            tcp/''*|tcp4/''*|tcp6/''*|unix/''*)
                echo "${i}"
                ;;
            # ... if not check if the path is accessible
            # and has a valid "fonts.dir" index
            *)
                [ -f "${i}/fonts.dir" ] && echo "${i}"
                ;;
        esac
    done
}

# Build a comma-seperated list of fonts (font path) from a list of fonts
fontlist2fontpath()
{
    fp=""
    read fp;
    while read i ; do
        fp="${fp},${i}"
    done
    
    echo "$fp"
}

# Build a list (one item per line) of fonts from a font path
fontpath2fontlist()
{
    while read i ; do
        echo "${i}" | tr "," "\n"
    done
}

# Sort scaleable fonts (PS Type1 and TrueType) first in a font list
sort_scaleable_fonts_first()
{
    i="$(fontlist2fontpath)"
    # First list PS Type1 fonts...
    echo "${i}" | fontpath2fontlist | fgrep "/Type1"
    # ... then TrueType fonts ...
    echo "${i}" | fontpath2fontlist | egrep -i "/TrueType|/TT(/$|$)|/TTF(/$|$)"
    # ... then all others
    echo "${i}" | fontpath2fontlist | egrep -v -i "/Type1|/TrueType|/TT(/$|$)|/TTF(/$|$)"
}

# Check if a X display is used by a Xserver or not
# Known bugs:
# - there is no way in plain bourne shell or bash (see comment about ksh93
#   below) to test if a Xserver sits only on a socket and not on a pipe
# - some Xserver's don't cleanup their stuff in /tmp on exit which may end
#   in the problem that we don't detect possible free display numbers
#   (one problem is that only ksh93 can do stuff like 
#   "cat </dev/tcp/0.0.0.0/6001")
CheckIfDisplayIsInUse()
{
    id=$1
    
    [ -r "/tmp/.X${id}-lock"     ] && return 0;
    [ -r "/tmp/.X11-unix/X${id}" ] && return 0;
    [ -r "/tmp/.X11-pipe/X${id}" ] && return 0;
    
    return 1;
}

lastdisplaynumreturned_store=/tmp/.Xp_last_display_returned_by_findfreexdisplaynum_${RANDOM}_${RANDOM}

# Try to find a free display number
FindFreeXDisplayNum()
{
    if [ -r "${lastdisplaynumreturned_store}" ] ; then
      i="$(cat "${lastdisplaynumreturned_store}")"
    else
      i=32 # start at display 32
    fi
    
    while [ $i -lt 127 ] ; do
        i=$(($i + 1))

        if CheckIfDisplayIsInUse $i ; then
            true
        else
            echo "$i"
            echo "$i" >"${lastdisplaynumreturned_store}"
            return 0
        fi
    done

    # Using "magic" value of 189 here due lack of a better solution
    echo "189"
    echo "189" >"${lastdisplaynumreturned_store}"    
    return 0
}

# Check if a process exists or not
pexists()
{
    [ "$1" = "" ] && return 1;

    # Use of /proc would be better but not all platforms (like AIX) have procfs
    [ "$(ps -p $1 | fgrep $1)" != "" ] && return 0;
    return 1
}

# Check if there is a spooler running...
is_spooler_running()
{
    # This covers Linux lpd, CUPS, Solaris and AIX 4.x - but what about
    # AIX 5.x, HP-UX and IRIX ?

    [ "$(ps -A | egrep 'lpd|lpsched|cupsd|qdaemon' | fgrep -v 'grep')" != "" ] && return 0;
    return 1
}

# Wait until the spooler system has been started (but not more than 30secs)
wait_for_print_spooler()
{
    for i in 1 2 3 4 5 6 7 8 9 10 ; do
        is_spooler_running && return 0;
        sleep 3
    done
    
    return 0
}

lock_server_registry()
{
    lock_counter=0 # counts in 1/100s
    waiting_for_lock_msg_send="false"
    while ! mkdir "${XP_SERVERS}.lock" 2>/dev/null ; do
        # print notice after 2 seconds
        if [ ${lock_counter} -gt 200 -a "${waiting_for_lock_msg_send}" != "true" ] ; then
            echo "${0}: waiting for lock(=${XP_SERVERS}.lock)..."
            waiting_for_lock_msg_send="true"
        fi

        # tread the lock as "broken" after 20 seconds
        if [ ${lock_counter} -gt 2000 ] ; then
            echo "${0}: WARNING: lock timeout for lock(=${XP_SERVERS}.lock)."
            return 0
        fi
                
        if [ -x /bin/usleep ] ; then
            /bin/usleep 200000
            lock_counter=$((${lock_counter} + 20)) # 20/100s
        else
            sleep 1
            lock_counter=$((${lock_counter} + 100)) # 100/100s
        fi
    done
}

unlock_server_registry()
{
    rmdir "${XP_SERVERS}.lock"
}

# Kill dead registry locks (silently!)
kill_dead_registry_locks()
{
    rm -Rf "${XP_SERVERS}.lock"
}

# Start Xprint servers
start_servers()
{
    # Write registry "intro" ...
    lock_server_registry
    echo "# Xprint server list"                               >>"${XP_SERVERS}"
    echo "# File is for private use for ${0}."                >>"${XP_SERVERS}"
    echo "# Do not edit, rely on the content or file format." >>"${XP_SERVERS}"
    unlock_server_registry

    hostname="$(hostname)"

    default_fontpath="$(get_system_fontlist | fontlist2fontpath)"
    default_fontpath_acceptpattern=".*";
    default_fontpath_rejectpattern="_No_Match_"; # Match nothing   
    
    curr=0
    while [ $curr -lt $num_xpstart ] ; do
        if [ "${xpstart_remote_server[$curr]}" != "" ] ; then
            # Remote Xprt, just put the entry into the registry
            lock_server_registry
            echo "display=${xpstart_remote_server[$curr]}" >>"${XP_SERVERS}"
            unlock_server_registry
        else
            # Run block in seperate process to avoid that changes to the
            # xpstart_* variables affect the next cycle
            (
              # Use defaults if there are no special options
              [ "${xpstart_fontpath[$curr]}"               = "" ] &&               xpstart_fontpath[$curr]="${default_fontpath}";
              [ "${xpstart_fontpath_acceptpattern[$curr]}" = "" ] && xpstart_fontpath_acceptpattern[$curr]="$default_fontpath_acceptpattern";
              [ "${xpstart_fontpath_rejectpattern[$curr]}" = "" ] && xpstart_fontpath_rejectpattern[$curr]="$default_fontpath_rejectpattern";
              [ "${xpstart_displayid[$curr]}"              = "" ] &&              xpstart_displayid[$curr]="$(FindFreeXDisplayNum)"       
              [ "${xpstart_logger[$curr]}"                 = "" ] &&                 xpstart_logger[$curr]="logger -p lpr.notice -t Xprt_${xpstart_displayid[$curr]}";
              [ "${xpstart_logfile[$curr]}"                = "" ] &&                xpstart_logfile[$curr]="/dev/null";
              [ "${xpstart_xprt_binary[$curr]}"            = "" ] &&            xpstart_xprt_binary[$curr]="${XPRT_BIN}";
              if [ "${xpstart_xprt_binary[$curr]}" = "/usr/openwin/bin/Xprt" -o "$(uname -s)" = "SunOS" ] ; then
                  # Solaris /usr/openwin/bin/Xprt does not support "-nolisten tcp"
                  # yet nor is it possible to run a Xserver on a unix socket only
                  # in Solaris since access to the unix domain sockets in
                  # /tmp/.X11-pipe and /tmp/.X11-unix is restricted to applications
                  # with group-id "root" (e.g. the Xprt server would need to be
                  # setgid "root" that plain users can start it listening on a unix
                  # socket only)
                  [ "${xpstart_options[$curr]}" = "" ] && xpstart_options[$curr]="-ac -pn"
              else
                  [ "${xpstart_options[$curr]}" = "" ] && xpstart_options[$curr]="-ac -pn -nolisten tcp"
              fi

              # Check if the Xprt binary is available                                     
              if [ ! -x "${xpstart_xprt_binary[$curr]}" ] ; then                                            
                  error_echo "Can't find \"${xpstart_xprt_binary[$curr]}\"."                                  
                  exit 1 # exit block                                                               
              fi                                                                          

              # Verify and set location of font encodings directory file
              if [ "${xpstart_font_encodings_dir[$curr]}" = "" ] ; then
                  if [ -f "${XPROJECTROOT}/lib/X11/fonts/xf86encodings/encodings.dir" ] ; then
                      xpstart_font_encodings_dir[$curr]="${XPROJECTROOT}/lib/X11/fonts/xf86encodings/encodings.dir"
                  else
                      xpstart_font_encodings_dir[$curr]="${XPROJECTROOT}/lib/X11/fonts/encodings/encodings.dir";
                  fi
              fi

              unset FONT_ENCODINGS_DIRECTORY
              if [ ! -f "${xpstart_font_encodings_dir[$curr]}" ] ; then
                  warning_echo "Can't find \"${xpstart_font_encodings_dir[$curr]}\", TrueType font support may not work."
              fi

              export FONT_ENCODINGS_DIRECTORY="${xpstart_font_encodings_dir[$curr]}"

              # Generate font path (containing only valid font path elements)
              # from input font path and filter expressions
              curr_fp=$(echo "${xpstart_fontpath[$curr]}" | 
                        fontpath2fontlist |
                        filter_fontlist "${xpstart_fontpath_acceptpattern[$curr]}" "${xpstart_fontpath_rejectpattern[$curr]}" | 
                        filter_unsupported_fonts |
                        sort_scaleable_fonts_first | 
                        validate_fontlist | 
                        fontlist2fontpath)

              # Set Xserver auditing level option
              unset curr_audit
              if [ "${xpstart_auditlevel[$curr]}" != "" ] ; then
                  curr_audit="-audit ${xpstart_auditlevel[$curr]}"
              fi

              # Set Xprt -XpFile option
              unset curr_xpfile
              if [ "${xpstart_xpfile[$curr]}" != "" ] ; then
                  curr_xpfile="-XpFile ${xpstart_xpfile[$curr]}"
              fi

              # Set custom XPCONFIGDIR (if there is one)
              unset XPCONFIGDIR
              if [ "${xpstart_xpconfigdir[$curr]}" != "" ] ; then
                  export XPCONFIGDIR="${xpstart_xpconfigdir[$curr]}"
              fi

              # If someone uses "-nolisten tcp" make sure we do not add a hostname to force local transport
              if [ "$(echo "${xpstart_options[$curr]}" | egrep "nolisten.*tcp")" != "" ] ; then
                  xp_display=":${xpstart_displayid[$curr]}"
              else
                  xp_display="${hostname}:${xpstart_displayid[$curr]}"
              fi
              
              (
                (
                  "${xpstart_xprt_binary[$curr]}"                       ${xpstart_options[$curr]}                       ${curr_xpfile} ${curr_audit}                       -fp ${curr_fp}                       :${xpstart_displayid[$curr]} &




                  server_pid="$!"
 
                  # Append the new server to the registry
                  lock_server_registry
                  echo "display=${xp_display} display_id=${xpstart_displayid[$curr]} pid=${server_pid}" >>"${XP_SERVERS}"
                  unlock_server_registry
                  
                  wait
                  echo "Xprint server pid=${server_pid} done, exitcode=$?."
                  
                  # Remove the dead server from the registry
                  # (only if the registry still exists - if /etc/init.d/xprint stop" gets called the registry
                  # will be removed - and we should not re-create it afterwards...)
                  lock_server_registry
                  if [ -f "${XP_SERVERS}" ] ; then
                      x="$(cat "${XP_SERVERS}")" # Store content of file "${XP_SERVERS}" in var "x"
                      echo "${x}" | fgrep -v "display_id=${xpstart_displayid[$curr]} pid=${server_pid}" >"${XP_SERVERS}"
                  fi
                  unlock_server_registry                 
                ) 2>&1 | while read i ; do echo "$i" | tee -a "${xpstart_logfile[$curr]}" | ${xpstart_logger[$curr]} ; done
              ) &
            )
        fi
        
        curr=$(($curr + 1))
    done
    
    # Remove tmp. file created by |FindFreeXDisplayNum()|
    rm -f "${lastdisplaynumreturned_store}"

    # Done.
    lock_server_registry
    echo "# EOF." >>"${XP_SERVERS}"
    unlock_server_registry
    return 0
}


# Convenience function to check setup and start Xprt server(s)
do_start()
{
    if [ -f "${XP_SERVERS}" ] ; then
        numservers="$(do_get_xpserverlist | wc -l)"
        if [ ${numservers} -gt 0 ] ; then
            verbose_echo "Xprint servers are already running."
            return 0
        else
            verbose_echo "Old server registry found, cleaning-up..."
            do_stop
        fi
    fi
    
    # Check if we can write the registry file
    touch "${XP_SERVERS}" 2>/dev/null
    if [ ! -f "${XP_SERVERS}" ] ; then
        error_echo "Cannot create \"${XP_SERVERS}\"."
        # exit code 4 = user had insufficient privilege (LSB)
        exit 4
    fi

    if ! setup_config ; then
        error_echo "setup_config failed."
        exit 1
    fi

    # Provide two paths here - one which simply starts the Xprt servers,
    # assuming that there is a print spooler already running (or that 
    # ${XPCONFIG}/C/print/Xprinters provides static print queue entries
    # (like for the PSspooldir print model)) and a 2nd path which
    # explicitly checks if the print queue daemons are running
    if true ; then
        msg "Starting Xprint servers: Xprt."
        start_servers
    else 
        # Continue in the background if there is no spooler running yet (that
        # we don't hold off the boot process nor run in a possible race-condition
        # when /etc/init.d/lpd was not called yet but the runlevel script waits
        # for us to finish first ...
        if is_spooler_running ; then
            msg "Starting Xprint servers: Xprt."
            start_servers
        else
            msg "Starting Xprint servers (in the background): Xprt."
            (wait_for_print_spooler ; start_servers) &
            sleep 5
        fi
    fi
    
    if [ "${CURRLOGNAME}" = "root" -a -d /var/lock/subsys/ ] ; then
        touch /var/lock/subsys/xprint
    fi
}

# Convenience function to stop Xprt server(s)
do_stop()
{
    msg "Stopping Xprint servers: Xprt."

    lock_server_registry
    if [ -f "${XP_SERVERS}" ] ; then       
        reglist="$(cat "${XP_SERVERS}")"
        rm -f "${XP_SERVERS}"
    fi
    unlock_server_registry
    
    if [ "${reglist}" != "" ] ; then
        echo "${reglist}" |
          grep "^display=.*:.* pid=[0-9]*$" |
          while read i ; do
              (
                eval ${i}
                if pexists ${pid} ; then 
                    kill ${pid}
                fi

                # Remove the X sockets/pipes which are not in use anymore
                # (It would be better if the Xservers would cleanup this
                # automatically, but most Xservers do not do that... ;-(
                # Note that this will not work on Solaris where applications
                # must run with groupid="root" if they want to write into
                # /tmp/.X11-unix/ and/or /tmp/.X11-pipe/)
                if [ "${display_id}" != "" ] ; then
                    rm -f "/tmp/.X${display_id}-lock"     2>/dev/null
                    rm -f "/tmp/.X11-unix/X${display_id}" 2>/dev/null
                    rm -f "/tmp/.X11-pipe/X${display_id}" 2>/dev/null
                fi 
              )
          done
    fi

    if [ "${CURRLOGNAME}" = "root" -a -d /var/lock/subsys/ ] ; then
        rm -f /var/lock/subsys/xprint
    fi
    
    # Remove any outstanding (dead) locks and cleanup
    rm -f "${XP_SERVERS}"
    kill_dead_registry_locks
}

# Convenience function to obtain a list of available Xprint servers
do_get_xpserverlist()
{
    if [ -f "${XP_PER_USER_SERVERS}" -o -f "${XP_GLOBAL_SERVERS}" ] ; then
        xpserverlist=$(
          # Enumerate both per-user and global servers (in that order)
          (
            [ -f "${XP_PER_USER_SERVERS}" ]  && cat "${XP_PER_USER_SERVERS}"
            [ -f "${XP_GLOBAL_SERVERS}"   ]  && cat "${XP_GLOBAL_SERVERS}"
          ) |
            egrep "^display=.*:.* pid=[0-9]*$|^display=.*:[0-9]*$" |
              while read i ; do
                  (
                    pid="none"
                    eval ${i}
                    # Check if the Xprt process exists (if possible)
                    if [ "$pid" != "none" ] ; then
                        if pexists ${pid} ; then
                            echo ${display}
                        fi
                    else
                        echo ${display}
                    fi
                  )
              done | tr "\n" " "
          )
        # Only produce output if we have some entries...
        [ "${xpserverlist}" != "" ] && echo "${xpserverlist}"
    fi
}

do_restart()
{
    msg "Restarting Xprint server(s): Xprt."
    do_stop
    sleep 1
    do_start
}

do_diag()
{
    echo "##### Diag start $(date)."
    
    # General info
    echo "## General info start."
    (
      echo "PATH=\"${PATH}\""
      echo "TZ=\"${TZ}\""
      echo "LANG=\"${LANG}\""
      echo "uname -a=\"$(uname -a)\""
      echo "uname -s=\"$(uname -s)\""
      echo "uname -p=\"$(uname -p)\""
      echo "uname -i=\"$(uname -i)\""
      echo "uname -m=\"$(uname -m)\""
      echo "has /etc/SuSE-release ... $([ -f "/etc/SuSE-release" ] && echo "yes" || echo "no")"
      echo "has /etc/redhat-release ... $([ -f "/etc/redhat-release" ] && echo "yes" || echo "no")"
      echo "has /etc/debian_version ... $([ -f "/etc/debian_version" ] && echo "yes" || echo "no")"
      echo "how many Xprt servers are running ...$(ps -ef | fgrep Xprt | fgrep -v "grep" | wc -l)"
    ) 2>&1 | while read i ; do echo "  $i" ; done
    echo "## General info end."
    
    # Testing font paths
    echo "## Testing font paths start."
    (
      get_system_fontlist |
          filter_unsupported_fonts |
          sort_scaleable_fonts_first | 
          validate_fontlist | while read d ; do
          echo "#### Testing \"${d}\" ..."
          if [ ! -d "$d" ] ; then
              echo "# Error: $d does not exists."
              continue
          fi
          if [ ! -r "$d" ] ; then
              echo "# Error: $d not readable."
              continue
          fi
          if [ ! -f "${d}/fonts.dir" ] ; then
              echo "# Error: ${d}/fonts.dir not found."
              continue
          else
              if [ ! -r "${d}/fonts.dir" ] ; then
                  echo "# Error: ${d}/fonts.dir not readable."
                  continue
              fi
          fi
          if [ -f "${d}/fonts.alias" ] ; then
              if [ ! -r "${d}/fonts.alias" ] ; then
                  echo "# Error: ${d}/fonts.alias not readable."
              fi
          fi

          if [ "$(cat "${d}/fonts.dir" | fgrep 'cursor')" != "" ] ; then
              echo "${d}/fonts.dir has cursor font."
          fi
          if [ "$(cat "${d}/fonts.dir" | fgrep 'fixed')" != "" ] ; then
              echo "${d}/fonts.dir has fixed font."
          fi

          if [ -r "${d}/fonts.alias" ] ; then 
              if [ "$(cat "${d}/fonts.alias" | fgrep 'cursor')" != "" ] ; then
                  echo "${d}/fonts.alias has cursor font."
              fi
              if [ "$(cat "${d}/fonts.alias" | fgrep 'fixed')" != "" ] ; then
                  echo "${d}/fonts.alias has fixed font."
              fi
          fi

          linenum=0
          cat "${d}/fonts.dir" | while read i1 i2 i3 i4 ; do
              linenum=$((${linenum} + 1))
              [ ${linenum} -eq 1 ] && continue

              if [ ! -f "${d}/${i1}" ] ; then
                  echo "ERROR: ${d}/fonts.dir line ${linenum} has non-exististant font \"${i1}\" (=\"${i1} ${i2} ${i3} ${i4}\")"
              fi
          done
      done
    ) 2>&1 | while read i ; do echo "  $i" ; done
    echo "## Testing font paths end."
    
    echo "##### Diag End $(date)."
}

# Set platform-defaults for setup_config()
setup_config_defaults()
{
    curr_num_xpstart="${1}"
    
    #### Defaults for Linux/Solaris
    # Start Xprt using builtin XPCONFIGDIR at a free display numer
    # (Solaris(=SunOS5.x)'s /usr/openwin/bin/Xprt supports TrueType fonts,
    # therefore we don't need to filter them)
                      xpstart_fontpath[${curr_num_xpstart}]="";
        xpstart_fontpath_acceptpattern[${curr_num_xpstart}]=".*";
        xpstart_fontpath_rejectpattern[${curr_num_xpstart}]="/Speedo|/F3bitmaps|/F3";
                     xpstart_displayid[${curr_num_xpstart}]="";
                   xpstart_xpconfigdir[${curr_num_xpstart}]="";
                        xpstart_xpfile[${curr_num_xpstart}]="";
                    xpstart_auditlevel[${curr_num_xpstart}]="4";
                       xpstart_options[${curr_num_xpstart}]="";
                        xpstart_logger[${curr_num_xpstart}]="";
    # Check whether we have /dev/stderr (needed for old AIX + old Debian)
    if [ -w "/dev/stderr" ] ; then
                       xpstart_logfile[${curr_num_xpstart}]="/dev/stderr";
    else
                       xpstart_logfile[${curr_num_xpstart}]="/dev/tty";
    fi
                   xpstart_xprt_binary[${curr_num_xpstart}]="";

    # Custom rules for the GISWxprintglue package on Solaris
    # (which uses Solaris's /usr/openwin/bin/Xprt but a custom config)
    if [ "${XPCUSTOMGLUE}" = "GISWxprintglue" ] ; then
        xpstart_xpconfigdir[${curr_num_xpstart}]="/opt/GISWxprintglue/server/etc/XpConfig"
        xpstart_xprt_binary[${curr_num_xpstart}]="/usr/openwin/bin/Xprt"
    fi
    # Custom rules for the GISWxprint package on Solaris
    # (which uses both it's own Xprt and a custom config)
    if [ "${XPCUSTOMGLUE}" = "GISWxprint" ] ; then
        xpstart_xpconfigdir[${curr_num_xpstart}]="/opt/GISWxprint/server/etc/XpConfig"
        xpstart_xprt_binary[${curr_num_xpstart}]="/opt/GISWxprint/bin/Xprt"
        xpstart_font_encodings_dir[${curr_num_xpstart}]="/opt/GISWxprint/lib/X11/fonts/encodings/encodings.dir"
    fi
    
    #######################################################
    ###
    ### Debian Xprint package default configuration
    ###
    if [ "${XPCUSTOMGLUE}" = "DebianGlue" ] ; then
        # Set XPCONFIGDIR=/usr/share/Xprint/xserver
        xpstart_xpconfigdir[${curr_num_xpstart}]="/usr/share/Xprint/xserver";

        # Use fixed display ID (":64"), or else all client programs will have to be
        # restarted simply to update XPSERVERLIST to the latest ID when upgrading,
        # which would be a nightmare.
        xpstart_displayid[${curr_num_xpstart}]=64;

        # Do not send any messages to console
        xpstart_logfile[${curr_num_xpstart}]="/dev/null";

        # By default use binary provided by Debian's "xprt-xprintorg" package
        # (=/usr/bin/Xprt), otherwise leave blank (e.g. use script's default
        # (=/usr/X11R6/bin/Xprt))
        if [ -x "/usr/bin/Xprt" ] ; then
            xpstart_xprt_binary[${curr_num_xpstart}]="/usr/bin/Xprt";
        fi
    fi
    ###
    ### End Debian default configuration
    ###
    #######################################################
}

fetch_etc_initd_xprint_envvars()
{
    curr_num_xpstart="${1}"

    ## Process some $ETC_INITD_XPRINT_* vars after all which may be used by
    # a user to override the hardcoded values here when starting Xprt per-user
    # (a more flexible way is to provide an own setup config script in
    # "~./Xprint_per_user_startup" - see above)
    if [ "${ETC_INITD_XPRINT_XPRT_PATH}" != "" ] ; then
        xpstart_xprt_binary[${curr_num_xpstart}]="${ETC_INITD_XPRINT_XPRT_PATH}"
    fi
    if [ "${ETC_INITD_XPRINT_XPCONFIGDIR}" != "" ] ; then
        xpstart_xpconfigdir[${curr_num_xpstart}]="${ETC_INITD_XPRINT_XPCONFIGDIR}"
    fi
    if [ "${ETC_INITD_XPRINT_XPFILE}" != "" ] ; then
        xpstart_xpfile[${curr_num_xpstart}]="${ETC_INITD_XPRINT_XPFILE}"
    fi
    if [ "${ETC_INITD_XPRINT_LOGFILE}" != "" ] ; then
        xpstart_logfile[${curr_num_xpstart}]="${ETC_INITD_XPRINT_LOGFILE}"
    fi
    if [ "${ETC_INITD_XPRINT_DISPLAYID}" != "" ] ; then
        xpstart_displayid[${curr_num_xpstart}]="${ETC_INITD_XPRINT_DISPLAYID}"
    fi
    if [ "${ETC_INITD_XPRINT_FONTPATH}" != "" ] ; then
        xpstart_fontpath[${curr_num_xpstart}]="${ETC_INITD_XPRINT_FONTPATH}"
    fi
    if [ "${ETC_INITD_XPRINT_XPRT_OPTIONS}" != "" ] ; then
        xpstart_options[${curr_num_xpstart}]="${ETC_INITD_XPRINT_XPRT_OPTIONS}"
    fi
    if [ "${ETC_INITD_XPRINT_AUDITLEVEL}" != "" ] ; then
        xpstart_auditlevel[${curr_num_xpstart}]="${ETC_INITD_XPRINT_AUDITLEVEL}"
    fi
    if [ "${ETC_INITD_XPRINT_XF86ENCODINGSDIR}" != "" ] ; then
        xpstart_font_encodings_dir[${curr_num_xpstart}]="${ETC_INITD_XPRINT_XF86ENCODINGSDIR}"
    fi
}

############################################################################
# setup_config() sets the configuration parameters used to start one
# or more Xprint servers ("Xprt").
# The following variables are used:
# - "num_xpstart" - number of servers to start
# - "xpstart_fontpath[index]" - custom font path. Leave blank if you want
#   the platform-specific default
# - "xpstart_fontpath_acceptpattern[index]" - extended regular expression
#   (see egrep(1)) used to filter the font path - items only pass this
#   filter if they match the pattern (leave blank if you want to filter
#   nothing)
# - "xpstart_fontpath_rejectpattern[index]" - extended regular expression
#   (see egrep(1)) used to filter the font path - items only pass this
#   filter if they do not match the pattern (leave blank if you want to
#   filter nothing)
# - "xpstart_font_encodings_dir[index]" - location of "encodings.dir".
#   Leave blank to use the default.
# - "xpstart_displayid[index]" - display id to use for the Xprint server
#   (leave blank to choose the next available free display id)
# - "xpstart_xpconfigdir[index]" - value for custom XPCONFIGDIR (leave blank
#   if you don not want that that XPCONFIGDIR is set at Xprt startup)
# - "xpstart_xpfile[index]" - value used for Xprt's "-XpFile" option (leave
#   blank if you do not want to set this option)
# - "xpstart_auditlevel[index]" - set Xserver auditing level (leave blank to
#   use no auditing)
# - "xpstart_options[index]" - set further Xprt options (leave blank to set
#   no further options)
# - "xpstart_logger[index]" - utility which gets stderr/stdout messages from
#   Xprt and sends them to a logging daemon. Leave blank to use /usr/bin/logger
#   to send such messages to the lpr.notice syslog)
# - "xpstart_logfile[index]" - log file to append stderr/stdout messages from
#   Xprt to. Leave blank to send messages to /dev/null
# - "xpstart_xprt_binary[index]" - set custom Xprt binary (leave blank to use
#   the platform-specifc default)
setup_config()
{
    num_xpstart=0;
    
    if [ "${ETC_INITD_XPRINT_CUSTOM_SETUP_CONFIG}" != "" ] ; then
        user_cfg="${ETC_INITD_XPRINT_CUSTOM_SETUP_CONFIG}"
    else
        user_cfg="${HOME}/.Xprint_per_user_startup"
    fi
    
    # Source per-user ~/.Xprint_per_user_startup file if there is one
    # (and do not use the script's defaults below)
    if [ -r "${user_cfg}" ] ; then
        # Define API version which should be checked by ${HOME}/.Xprint_per_user_startup
        # ${HOME}/.Xprint_per_user_startup should bail-out if the version differ
        etc_initd_xprint_api_version=2
        
        # Source per-user settings script
        . "${user_cfg}"
        
        # done with setting the config for per-user Xprt instances
        return 0;
    else
        # Use /etc/init.d/xprint's builtin config
        # Each entry should start with |setup_config_defaults| to pull the
        # platform defaults and finish with |num_xpstart=$(($num_xpstart + 1))|
        # to end the entry
        
        # Set platform-defaults
        setup_config_defaults "${num_xpstart}"

        ## -- snip --

        # Admins can put their stuff "in" here...

        ## -- snip --

        # Override script's builtin values with those a user may set via the
        # $ETC_INIITD_XPRINT_* env vars
        fetch_etc_initd_xprint_envvars "${num_xpstart}"

        num_xpstart=$((${num_xpstart} + 1))

        return 0;
    fi

    #### Sample 1:
    # # Start Xprt on a free display ID with custom XPCONFIGDIR and without
    # # Speedo and TrueType fonts
    #    xpstart_fontpath_rejectpattern[$num_xpstart]="/Speedo|/TrueType|/TT(/$|$)|/TTF(/$|$)";
    #               xpstart_xpconfigdir[$num_xpstart]="/home/gisburn/cwork/Xprint/Xprt_config/XpConfig";
    #                xpstart_auditlevel[$num_xpstart]="4";
    #                   xpstart_options[$num_xpstart]="-ac -pn";
    #num_xpstart=$(($num_xpstart + 1))


    #### Sample 2: 
    # # Start Xprt without TrueType fonts on a display 55 with custom
    # # XPCONFIGDIR
    #    xpstart_fontpath_rejectpattern[$num_xpstart]="/TrueType|/TT(/$|$)|/TTF(/$|$)";
    #                 xpstart_displayid[$num_xpstart]=55;
    #               xpstart_xpconfigdir[$num_xpstart]="/home/gisburn/cwork/Xprint/Xprt_config/XpConfig";
    #                xpstart_auditlevel[$num_xpstart]=4;
    #                   xpstart_options[$num_xpstart]="-ac -pn";
    #num_xpstart=$(($num_xpstart + 1))

    #### Sample 3: 
    # # Start Xprt without TrueType fonts on a display 56 with custom
    # # XPCONFIGDIR and alternate "Xprinters" file
    #    xpstart_fontpath_rejectpattern[$num_xpstart]="/TrueType|/TT(/$|$)|/TTF(/$|$)";
    #                 xpstart_displayid[$num_xpstart]=56;
    #               xpstart_xpconfigdir[$num_xpstart]="/etc/XpConfig/default";
    #                    xpstart_xpfile[$num_xpstart]="/etc/XpConfig/default/Xprinters_test2"
    #                xpstart_auditlevel[$num_xpstart]="4";
    #                   xpstart_options[$num_xpstart]="-ac -pn";
    #               xpstart_xprt_binary[$num_xpstart]="";
    #num_xpstart=$(($num_xpstart + 1))

    #### Sample 4:
    # # Start Xprt with Solaris ISO-8859-7 (greek(="el") locale) fonts on
    # # display 57
    #                  xpstart_fontpath[$num_xpstart]="/usr/openwin/lib/locale/iso_8859_7/X11/fonts/75dpi,/usr/openwin/lib/locale/iso_8859_7/X11/fonts/Type1,/usr/openwin/lib/X11/fonts/misc/";
    #    xpstart_fontpath_acceptpattern[$num_xpstart]="";
    #    xpstart_fontpath_rejectpattern[$num_xpstart]="_No_Match_";
    #                 xpstart_displayid[$num_xpstart]="57";
    #                xpstart_auditlevel[$num_xpstart]="4";
    #                   xpstart_options[$num_xpstart]="-ac -pn";
    #num_xpstart=$(($num_xpstart + 1))

    #### Sample 5:
    # # Start Xprt with the font list of an existing Xserver (excluding Speedo fonts) on
    # # display 58
    # # Note that this only works within a X session. At system boot time
    # # there will be no $DISPLAY to fetch the information from!!
    #                  xpstart_fontpath[$num_xpstart]="$(get_fontlist_from_display ${DISPLAY} | fontlist2fontpath)";
    #    xpstart_fontpath_acceptpattern[$num_xpstart]="";
    #    xpstart_fontpath_rejectpattern[$num_xpstart]="";
    #                 xpstart_displayid[$num_xpstart]="58";
    #               xpstart_xpconfigdir[$num_xpstart]="";
    #                xpstart_auditlevel[$num_xpstart]="4";
    #                   xpstart_options[$num_xpstart]="-ac -pn";
    #               xpstart_xprt_binary[$num_xpstart]="";
    #num_xpstart=$(($num_xpstart + 1))

    #### Sample 6:
    # # List remote Xprt's here 
    # # (note that there is no test to check whether these DISPLAYs are valid!)
    #             xpstart_remote_server[$num_xpstart]="sera:12"    ; num_xpstart=$(($num_xpstart + 1))
    #             xpstart_remote_server[$num_xpstart]="gandalf:19" ; num_xpstart=$(($num_xpstart + 1))   
}

############################################################################

# Main
case "$1" in
    ## Start Xprint servers
    'start')
        do_start
        ;;

    ## Stop Xprint servers
    # Note that this does _not_ kill Xprt instances started using this script 
    # by non-root users
    'stop')
        do_stop
        ;;

    ## Restart Xprint servers
    'restart'|'force-reload')
        do_restart
        ;;

    ## Reload configuration without stopping and restarting
    'reload')
        # not supported
        msg "reload not supported, use 'restart' or 'force-reload'"
        exit 3
        ;;

    ## Restart Xprint only if it is already running
    'condrestart'|'try-restart')
        # only restart if it is already running
        [ -f /var/lock/subsys/xprint ] && do_restart || :
        ;;
    
    ## Get list of all Xprint servers for this user
    # (incl. per-user and system-wide instances)    
    'get_xpserverlist')
        do_get_xpserverlist
        ;;

    ## Get status of Xprint servers, RedHat-style
    'status')
        x="$(do_get_xpserverlist)"
        if [ "${x}" != "" ] ; then
            msg "Xprint (${x}) is running..."
            exit 0
        else
            msg "Xprint is stopped"
            exit 3
        fi 
        ;;
        
    ## Wrapper
    'wrapper')
        cmd="${2}"
        [ "${cmd}" = "" ] && fatal_error "No command given."
        shift ; shift
        export XPSERVERLIST="$(do_get_xpserverlist)"
        [ "${XPSERVERLIST}" = "" ] && fatal_error "No Xprint servers found."
        exec "${cmd}" "$@"
        ;;

    ## Wrapper for "xplsprinters"
    'lsprinters')
        [                  "${ETC_INITD_XPRINT_XPLSPRINTERS_PATH}" != "" ] && cmd="${ETC_INITD_XPRINT_XPLSPRINTERS_PATH}"
        [ "${cmd}" = "" -a "${XPCUSTOMGLUE}" = "GISWxprintglue"          ] && cmd="/opt/GISWxprintglue/bin/xplsprinters"
        [ "${cmd}" = "" -a "${XPCUSTOMGLUE}" = "GISWxprint"              ] && cmd="/opt/GISWxprint/bin/xplsprinters"
        [ "${cmd}" = "" -a "${XPROJECTROOT}" != ""                       ] && cmd="${XPROJECTROOT}/bin/xplsprinters"
        [ "${cmd}" = ""                                                  ] && cmd="xplsprinters"

        shift
        export XPSERVERLIST="$(do_get_xpserverlist)"
        [ "${XPSERVERLIST}" = "" ] && fatal_error "No Xprint servers found."
        exec "${cmd}" "$@"
        ;;

    ## Diagnostics
    'diag')
        do_diag
        ;;
    
    ## Print usage
    *)
        msg "Usage: $0 { start | stop | restart | reload | force-reload | status | condrestart | try-restart | wrapper | lsprinters | get_xpserverlist | diag }"
        exit 2
esac
exit 0

# EOF.
