#!/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 16 # description: Startup/shutdown script for Xprint server(s) # # processname: Xprt # 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: $syslog $network # Required-Stop: $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'". # ############################################################################ # ############################################################################ if [ -f /etc/init.d/functions ]; then source /etc/init.d/functions elif [ -f /etc/rc.d/init.d/functions ]; then source /etc/rc.d/init.d/functions fi 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}" } msgn() { echo -n "${1}" } ############################################################################ # 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/X11/fs/config" get_fontlist_from_xfs_config "${XPROJECTROOT}/lib/X11/fs/config" 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/xfs/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() { ( get_fontlist_from_defoma get_fontlist_from_xf86config # Getting font paths from XFS is mainly required for compatibilty to RedHat get_fontlist_from_all_xfs_configs ## List all fonts in all locales installed on this machine ( [ -d "/usr/share/fonts" ] && find /usr/share/fonts -name fonts.dir find /usr/X11R6/lib/X11/xserver/C/print/fonts "${XPROJECTROOT}/lib/X11/fonts" -name fonts.dir ) | while read i ; do echo "${i%/fonts.dir}" ; done ) | sort -u } # 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 ) <&- >&- 2>&- & ) 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 echo_failure verbose_echo "Xprint servers are already running." return 0 else echo_failure 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 echo_failure error_echo "Cannot create \"${XP_SERVERS}\"." # exit code 4 = user had insufficient privilege (LSB) exit 4 fi if ! setup_config ; then echo_failure 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 msgn "Starting Xprint servers: Xprt." start_servers && echo_success || echo_failure echo 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 msgn "Starting Xprint servers: Xprt." start_servers && echo_success || echo_failure echo else msgn "Starting Xprint servers (in the background): Xprt." (wait_for_print_spooler ; start_servers && echo_success || echo_failure) & echo 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 rc=$? [ "$rc" -eq 0 ] && echo_failure || echo_success } # 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/mandriva-release ... $([ -f "/etc/mandriva-release" ] && echo "yes" || echo "no")" echo "has /etc/mandrakelinux-release ... $([ -f "/etc/mandrakelinux-release" ] && echo "yes" || echo "no")" echo "has /etc/mandrake-release ... $([ -f "/etc/mandrake-release" ] && echo "yes" || echo "no")" 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.