MOON
Server: Apache/2.2.23 (Unix) mod_ssl/2.2.23 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 PHP/5.4.10
System: Linux vps.presagepowered.net 2.6.18-398.el5 #1 SMP Tue Sep 16 20:51:48 EDT 2014 i686
User: mckernan (512)
PHP: 5.4.10
Disabled: NONE
Upload Files
File: //usr/local/ssl/sbin/prl-xorgconf-fixer
#!/bin/sh
# vim:ts=4:sw=4:expandtab

# Copyright (c) 2005-2009 Parallels Inc.
# All Rights Reserved
#
# http://www.parallels.com
#
# This script is a part of Parallels Tools for Linux
#
#
# This script check and fixes broken xorg.conf
# Following issues can be handled:
# * missing Parallels mouse section
# * missing or unset AllowEmptyInput section
# * missing SendCoreEvents option (SCE) of non-parallels mouse
# * unneeded 'CorePointer' option (CP) for non-parallels mouse




# Exit codes
EXIT_OK=0
EXIT_ERR_MISSING_MOUSE=2
EXIT_ERR_MISSING_ALLOWEMPTYINPUT=3
EXIT_ERR_ALLOWEMPTYINPUT_FOUND=4
EXIT_ERR_MISSING_SCE=5
EXIT_ERR_UNNEEDED_CP=6
EXIT_ERR_CANNOT_FIX_MOUSE=12
EXIT_ERR_CANNOT_FIX_ALLOWEMPTYINPUT=13
EXIT_ERR_CANNOT_FIX_SCE=14
EXIT_ERR_CANNOT_FIX_CP=15


# Check if Parallels Mouse section is present.
# $1 - file to check
# Returns 0 if section found, else 1
pxcf_check_prl_mouse () {	
    grep -iqs '^[[:space:]]*Driver[[:space:]]\+"prlmouse"' "${1}"
}



# Check if option `AllowEmptyInput'/'AutoAddDevices' exists
# $1 - file to check
pxcf_check_allowemptyinput_exists_any () {
    cmd_l='^[[:space:]]*Option[[:space:]]\+'
    cmd_r='[[:space:]]\+"\?"\?'
    grep -iqs "$cmd_l\"AllowEmptyInput\"$cmd_r" "${1}" ||
    grep -iqs "$cmd_l\"AutoAddDevices\"$cmd_r" "${1}"
    return $?
}
pxcf_check_allowemptyinput_exists_both_yes () {
    cmd_l='^[[:space:]]*Option[[:space:]]\+'
    cmd_r='[[:space:]]\+"\?\(yes\|on\|1\|true\)"\?'
    grep -iqs "$cmd_l\"AllowEmptyInput\"$cmd_r" "${1}" &&
    grep -iqs "$cmd_l\"AutoAddDevices\"$cmd_r" "${1}"
    return $?
}

# Check if option 'SendCoreEvents' is set to positive value for non-parallels mouse
# $1 - file to check
pxcf_check_mouse_sce_yes() {

    awk '
    BEGIN {
        in_inputdevice_section = 0
        non_prlmouse_section = 0
        sce_option_yes = 0
    }
    {
        input_line = tolower($0)
        if (input_line ~ /^[\t ]*section[\t ]+"inputdevice"/)
            in_inputdevice_section = 1
        if (in_inputdevice_section == 1 && input_line ~ /^[\t ]*driver[\t ]+"mouse"/)
            non_prlmouse_section = 1
        if (in_inputdevice_section == 1 && input_line ~ /^[\t ]*option[\t ]+"sendcoreevents"[\t ]+"(yes|1|true|on)"/)
            sce_option_yes = 1
        if (in_inputdevice_section == 1 && input_line ~ /^[\t ]*endsection/)
        {
            if (non_prlmouse_section == 1 && sce_option_yes == 0)
                print "sce_no"
            in_inputdevice_section = 0
            sce_option_no = 0
            non_prlmouse_section = 0
        }   
    }
    ' "$1" | grep -q 'sce_no' && return 1

    return 0
}


# Check if some input devices have unneeded "CorePointer" option (except "Parallels Mouse")
# For now the logic is that only "Parallels Mouse" should have such option
# $1 - file to check
pxcf_check_unneeded_cp() {

    ! grep -ivs '^[[:space:]]*InputDevice[[:space:]]\+"Parallels Mouse"[[:space:]]\+"CorePointer"' "${1}" | \
        grep -iqs '^[[:space:]]*InputDevice[[:space:]]\+"[[:alnum:]_ ]\+"[[:space:]]\+"CorePointer"'
}


# Added option 'SendCoreEvents' to positive value for all non-parallels mouses
# $1 - source file
# $2 - target file
pxcf_add_mouse_sce_yes() {

    awk '
    BEGIN {
        idx = 0
        in_inputdevice_section = 0
        add_sce = 1
    }
    {
        input_line = tolower($0)
        if (input_line ~ /^[\t ]*section[\t ]+"inputdevice"/)
            in_inputdevice_section = 1
        if (in_inputdevice_section == 1)
        {
            if (input_line !~ /^[\t ]*option[\t ]+"sendcoreevents"[\t ]+"(no|0|false|off)"/)
            {
                items[idx] = $0
                ++idx
                if (input_line ~ /^[\t ]*option[\t ]+"sendcoreevents"[\t ]+"(yes|1|true|on)"/)
                    add_sce = 0
                # Dont need SCE option for all input devices with driver different to "mouse"
                if (input_line ~ /^[\t ]*driver[\t ]+"[A-Za-z0-9_]+"/ && tolower($2) !~ /"mouse"/)
                    add_sce = 0
            }
        }
        else
            print $0

        if (in_inputdevice_section == 1 && input_line ~ /^[\t ]*endsection/)
        {
            # Print out InputDevice section
            for (i = 0; i < idx - 1; ++i)
                print items[i]
            # Add SCE option if needed
            if (add_sce == 1)
                printf "\tOption\t\"SendCoreEvents\"\t\"yes\"\n"
            # And print out the last EndSection line
            print items[idx - 1]
            idx = 0
            in_inputdevice_section = 0
            add_sce = 1
        }
        
    }' "${1}" > "${2}"
}


# Delete 'CorePointer' option from all input devices except 'Parallels Mouse'
# $1 - source file
# $2 - target file
pxcf_del_unneeded_cp() {

    awk '
    {
        if (tolower($0) ~ /^[\t ]*inputdevice[\t ]+"parallels mouse"/)
            print;
        else if (tolower($0) ~ /^[\t ]*inputdevice[\t ]+"[a-z0-9_ ]+"[\t ]+"corepointer"/)
        {
            s = $0
            sub("[\t ]+\"[Cc][Oo][Rr][Ee][Pp][Oo][Ii][Nn][Tt][Ee][Rr]\"", "", s)
            print s;
        }
        else
            print;
    }' "${1}" > "${2}"
}


# Delete option `AllowEmptyInput'/'AutoAddDevices' at all
# $1 - file to modify
pxcf_del_allowemptyinput () {
    cmd_l='/^[[:space:]]*Option[[:space:]]\+'
    cmd_r='[[:space:]]\+"\?"\?/d'
    sed -i "$cmd_l\"AllowEmptyInput\"$cmd_r" "${1}"
    sed -i "$cmd_l\"AutoAddDevices\"$cmd_r" "${1}"
}

# Add Parallels Mouse section to xorg.conf
# $1 - source file 
# $2 - target file
pxcf_add_prl_mouse () {
    status=0

    # Activate Parallels Mouse in default server layout
    awk '
        {
                print;
                if ($0 ~ /^[\t ]*Section[\t ]+"ServerLayout"/)
                        print "\tInputDevice\t\"Parallels Mouse\"\t\"CorePointer\""
        }' "${1}" > "${2}"

    # Add section to xorg.conf
    cat >> "${2}" << EOF

# Parallels Mouse
Section "InputDevice"
    Identifier     "Parallels Mouse"
    Driver         "prlmouse"
    Option         "Device" "/dev/input/mice"
    Option         "Protocol" "auto"
EndSection

EOF

    status=$?

    return ${status}
}



# Add set 'AllowEmptyInput' section
# $1 - source file 
# $2 - target file
pxcf_add_allowemptyinput () {

    # Check if section 'ServerFlags' exists
    # If it does not exist add it and exit
    if ! grep -iqs \
        '^[[:space:]]*Section[[:space:]]\+"ServerFlags"' "${2}"; then
        cat >> "${2}" << EOF

Section "ServerFlags"
    Option         "AllowEmptyInput" "yes"
    Option         "AutoAddDevices" "yes"
EndSection

EOF
        return 0
    fi

    # First delete AllowEmptyInput/AutoAddDevices entries at all
    cmd_l='/^[[:space:]]*Option[[:space:]]\+'
    cmd_r='[[:space:]]\+"\?"\?/d'
    sed -i "$cmd_l\"AllowEmptyInput\"$cmd_r" "${1}"
    sed -i "$cmd_l\"AutoAddDevices\"$cmd_r" "${1}"

    # Now add AllowEmptyInput/AutoAddDevices both with yes values
    # just after the existing Section 'ServerFlags'
    awk '/^[[:space:]]*Section.*"ServerFlags"/ {
        print;
        print "\tOption\t\"AllowEmptyInput\"\t\"yes\"";
        print "\tOption\t\"AutoAddDevices\"\t\"yes\"";
        next; } {print} ' \
        "${1}" > "${2}"
}


# Check that given xorg.conf was patched by Parallels Tools installer.
# If, for example, given file was regenrated after PT installation there's no
# need to fix it by this script -- probably we'll just broke it.
pxcf_check_file_fixable() {
    # Try to find any of our typical patterns
    grep -iqs '^[[:space:]]*Driver[[:space:]]\+"prlvideo"' "${1}" && return 0
    grep -iqs '^[[:space:]]*Identifier[[:space:]]\+"Parallels Monitor"' "${1}" && return 0
    grep -iqs 'generated by Parallels Guest Tools' "${1}" && return 0
    # Seems file is not ours
    return 1
}


# Prints help on usage to stdout
# $1 - program name
pxcf_print_help () {
    echo "Usage: ${1#*/} ACTION file ..."
    echo "   ACTION:"
    echo "     check     checks if xorg givven is valid"
    echo "     fix       fixes given xorg"
    echo "     help      print this brief help"
    echo
}


# Prints error message
# all arguments are message to print
pxcf_error () {
    echo "$*" 1>&2
}


# Prints error message
# all arguments are message to print
pxcf_warning () {
    echo "$*" 1>&2
}

status=${EXIT_OK}

if test $# -lt 1; then
    pxcf_print_help $0 1>&2
    echo "ERROR: no action specified" 1>&2
    exit 1
fi

# AllowEmpyInput is required only for Xorg versions  >= 1.4
inputdevices_required=
allowemptyinput_required=
if type Xorg > /dev/null 2>&1; then
    XVERSION=$(Xorg -version 2>&1 | grep -i "x.org x server" | awk '{ print $4 }' | awk -F . '{ printf "%s.%s.%s", $1, $2, $3 }')
    if [ -z "$XVERSION" ]; then
        XVERSION=$(Xorg -version 2>&1 | grep -i "x window system version" | awk '{ print $5 }' | awk -F . '{ printf "%s.%s.%s", $1, $2, $3 }')
        if [ -z "$XVERSION" ]; then
            XVERSION=$(Xorg -version 2>&1 | grep -i "x protocol version" | awk '{ print $8 }' | awk -F . '{ printf "%s.%s", $1, $2 }')
        fi
    fi

	vmajor=$(echo $XVERSION | awk -F . '{ printf "%s", $1 }')
	vminor=$(echo $XVERSION | awk -F . '{ printf "%s", $2 }')
	vpatch=$(echo $XVERSION | awk -F . '{ printf "%s", $3 }')

    if [ "$vmajor" -ge "6" ]; then
    # Must discount major version,
    # because XOrg changes versioning logic since 7.3 (7.3 -> 1.3)
        vmajor=$(($vmajor - 6))
    fi

	v=$(($vmajor*1000000 + $vminor*1000))
	if [ -n "$vpatch" ]; then
		v=$(($v + $vpatch))
	fi

    allowemptyinput_required='no'
    if [ "$v" -ge "1004000" ]; then
    # Starting from XServer 1.4 we are must configure udev,
    # to properly init input devices, in this purposes we will add
    # AllowEmpyInput/AutoAddDevices option for xserver
        allowemptyinput_required='yes'
    fi
    inputdevices_required='yes'
    if [ "$v" -ge "1010000" ]; then
	# For new XServer's releases we drop old style InputDevices configuration entries
	# and will use udev only
        inputdevices_required='no'
    fi
fi

# Process actions
case "${1}" in
    fix)
        shift
        for file_to_fix in "$@"; do
            # Checke if file exists
            if [ ! -f "${file_to_fix}" ]; then
                pxcf_warning "File '${file_to_fix}' cannot be found. Skipping."
                continue
            elif [ ! -w "${file_to_fix}" ]; then
                pxcf_warning "File '${file_to_fix}' cannot be altered. Skipping."
                continue
            fi

            if ! pxcf_check_file_fixable "${file_to_fix}"; then
                pxcf_warning "File '${file_to_fix}' doesn't contain " \
                    "necessary Parallels Tools sections (replaced by somebody?). Skipping."
                continue
            fi

            file_to_fix=`readlink -f "${file_to_fix}"`
            source="${file_to_fix}.pxcf_backup"

            if ! pxcf_check_prl_mouse "${file_to_fix}"; then
                if  [ "$inputdevices_required" = "yes" ]; then
                    cp -f "${file_to_fix}" "${source}" 
                    pxcf_add_prl_mouse "${source}" "${file_to_fix}" || \
                        exit ${EXIT_ERR_CANNOT_FIX_MOUSE}
                fi
            fi
            
            if pxcf_check_allowemptyinput_exists_any "${file_to_fix}"; then
                if  [ "$allowemptyinput_required" != "yes" ]; then
                    pxcf_del_allowemptyinput "${file_to_fix}" || \
                        exit ${EXIT_ERR_CANNOT_FIX_ALLOWEMPTYINPUT}
                fi
            fi
            if ! pxcf_check_allowemptyinput_exists_both_yes "${file_to_fix}"; then
                if [ "$allowemptyinput_required" = "yes" ]; then
                    cp -f "${file_to_fix}" "${source}" 
                    pxcf_add_allowemptyinput "${source}" "${file_to_fix}" || \
                        exit ${EXIT_ERR_CANNOT_FIX_ALLOWEMPTYINPUT}
                fi
            fi

            if ! pxcf_check_mouse_sce_yes "${file_to_fix}"; then
                cp -f "${file_to_fix}" "${source}" 
                pxcf_add_mouse_sce_yes "${source}" "${file_to_fix}" || \
                    exit ${EXIT_ERR_CANNOT_FIX_SCE}
            fi

            if ! pxcf_check_unneeded_cp "${file_to_fix}"; then
                cp -f "${file_to_fix}" "${source}" 
                pxcf_del_unneeded_cp "${source}" "${file_to_fix}" || \
                    exit ${EXIT_ERR_UNNEEDED_CP}
            fi
            
            test -f "${srouce}" && rm -f "${source}"
        done
        ;;
    check)
        shift
        for file_to_fix in "$@"; do
            # Checke if file exists
            if [ ! -f "${file_to_fix}" ]; then
                pxcf_warning "File '${file_to_fix}' cannot be found. Skipping."
                continue
            fi

            # Run tests
            if ! pxcf_check_prl_mouse "${file_to_fix}"; then
                if  [ "$inputdevices_required" = "yes" ]; then
                    echo "No 'Parallels Mouse' section found in '${file_to_fix}'" 1>&2
                    status=${EXIT_ERR_MISSING_MOUSE}
                fi
            fi
    
            if pxcf_check_allowemptyinput_exists_any "${file_to_fix}"; then
                if [ "$allowemptyinput_required" != "yes" ]; then
                    echo "Options 'AllowEmptyInput/AutoAddDevices' exists and not required in '${file_to_fix}'" 1>&2
                    status=${EXIT_ERR_ALLOWEMPTYINPUT_FOUND}
                fi
            fi
            if ! pxcf_check_allowemptyinput_exists_both_yes "${file_to_fix}"; then
                if [ "$allowemptyinput_required" = "yes" ]; then
                    echo "Options 'AllowEmptyInput/AutoAddDevices' required in '${file_to_fix}'" 1>&2
                    status=${EXIT_ERR_MISSING_ALLOWEMPTYINPUT}
                fi
            fi

            if ! pxcf_check_mouse_sce_yes "${file_to_fix}"; then
                echo "'SendCoreEvents' option is not set to positive value in non-parallels mouse section in '${file_to_fix}'" 1>&2
                status=${EXIT_ERR_MISSING_SCE}
            fi

            if ! pxcf_check_unneeded_cp "${file_to_fix}"; then
                echo "non-parallels mouse pointer has 'CorePointer' option in '${file_to_fix}'" 1>&2
                status=${EXIT_ERR_UNNEEDED_CP}
            fi
        done
        ;;
    help)
        pxcf_print_help $0
        exit 0
        ;;
    *)
        pxcf_print_help $0 1>&2
        echo "Action '$1' is unknow" 1>&2
        exit 2
        ;;
esac

exit ${status}