#! /bin/bash
#
# Johannes Meixner <jsmeix@suse.de>, 2007, 2008, 2009, 2010, 2011

#set -x

# Make sure to have a clean environment:
export PATH="/sbin:/usr/sbin:/usr/bin:/bin"
export LC_ALL="POSIX"
export LANG="POSIX"
umask 022
# Disable bash file name globbing:
set -f

# This file name for a progress indicator is also used in Printer.ycp:
test -z "$PROGRESS" && PROGRESS="/var/lib/YaST2/create_printer_ppd_database.progress"

MY_NAME=${0##*/}

# Create temporary file names:
TMP_DATA=$(mktemp -u /tmp/$MY_NAME.XXXXXX)
TMP_DATA_RAW=$(mktemp -u /tmp/$MY_NAME.XXXXXX)

echo 'This file is used as progress indicator for DownloadProgress in Printer.ycp' >$PROGRESS
# Provide some amount of dummy content in the progress file so that the
# the DownloadProgress bar in YaST initially shows a first bit of progress
# to initially show to the user that something is actually going on:
for i in $( seq 20 )
do echo 'Dummy content so that DownloadProgress in YaST initially shows a first bit of progress' >>$PROGRESS
done

# Test if lpstat and lpinfo are executable:
echo 'Testing if lpstat and lpinfo are executable...' >>$PROGRESS
LPSTAT="$( type -P lpstat )"
if ! test -x "$LPSTAT"
then echo "Cannot execute lpstat" 1>&2
     exit 1
fi
LPINFO="$( type -P lpinfo )"
if ! test -x "$LPINFO"
then echo "Cannot execute lpinfo" 1>&2
     exit 1
fi

# Test if cupsd on localhost is accessible.
# Only on localhost print queues should be set up.
# CUPS supports even remote queue setup but this is not supported by YaST.
# Therefore explicitly the cupsd on localhost is asked for printer driver information.
echo 'Testing if cupsd on localhost is accessible...' >>$PROGRESS
# Since CUPS 1.4 'lpstat -r' results true even when scheduler is not running.
# Therefore we must now grep in its output:
if $LPSTAT -h localhost -r | grep -q 'scheduler is not running'
then echo "Cannot access cupsd on localhost" 1>&2
     exit 2
fi

# Input:

# Get the raw data:
echo 'Retrieving the raw data...' >>$PROGRESS
# Exit after timeout because then no empty YCP map is output
# so that either an existing YCP map could be used or YaST could also exit
# because without a PPD database printer setup makes not much sense.
# The very long timeout is usually only needed on slower machines
# and there also usually only once after a new system installation
# when the cupsd reads thousands of PPDs for the very first time
# (see Novell/Suse Bugzilla bnc#429397).
# Therefore the PROGRESS file can grow up to about 17000 bytes here:
MAXIMUM_WAIT="300"
$LPINFO -h localhost -l -m >$TMP_DATA_RAW &
lpinfoPID=$!
for i in $( seq $MAXIMUM_WAIT )
do ps $lpinfoPID &>/dev/null || break
   echo "Waiting for response from $LPINFO (PID $lpinfoPID)..." >>$PROGRESS
   sleep 1
done
if ps $lpinfoPID &>/dev/null
then kill -9 $lpinfoPID &>/dev/null
     echo "Aborted lpinfo after $MAXIMUM_WAIT seconds timeout." 1>&2
     echo "Aborted lpinfo after $MAXIMUM_WAIT seconds timeout." >>$PROGRESS
     exit 3
fi

# Process the data:
echo 'Got the raw data.' >>$PROGRESS
# Extract what is needed, quotation marks " are replaced by ' :
tr '"' "'" <$TMP_DATA_RAW | grep -E '^Model:|name =|make-and-model =|device-id =|natural_language =' >$TMP_DATA

# Have "^Model:" on a seperated "Model" line and convert " = " to a single space:
sed -i -e 's/^Model:/Model\n/' \
       -e 's/ = / /' $TMP_DATA

# Condense multiple spaces, convert tabs to blanks, and remove leading and trailing spaces:
sed -i -e 's/[[:space:]][[:space:]]*/ /g' \
       -e 's/^[[:space:]]*//' \
       -e 's/[[:space:]]*$//' $TMP_DATA

# Output:
echo 'Creating the YCP map...' >>$PROGRESS
# Output header:
echo "[" 

# Function to output one entry.
# Limit what is written to the PROGRESS file here to 4 characters per PPD.
# Otherwise the PROGRESS file would grow up too much here
# which would make the above "waiting for lpinfo" part too small
# to be really visible in the DownloadProgress bar in YaST.
Output()
{ if [ -n "$PPD" -a -n "$NICKNAME" ]
  then echo -e "  \$[ \"ppd\":\"$PPD\",\n     \"nickname\":\"$NICKNAME\",\n     \"deviceID\":\"$ID\",\n     \"language\":\"$LANGUAGE\",\n     \"manufacturer\":\"$MANUFACTURER\",\n     \"modelname\":\"$MODELNAME\"\n  ],"
  echo "$NICKNAME" | cut -b-4 >>$PROGRESS
  fi
}

# Make complete and seperated entries:
# The values are collected until a new "Model" line appears, then the values are output.
# The very first "Model" line doesn't result an output because "$PPD" and "$NICKNAME" are empty strings.
exec <$TMP_DATA
while read KEY VALUE
do case "$KEY" in
        Model) Output
               PPD=""
               NICKNAME=""
               ID=""
               LANGUAGE="" ;;
        name) PPD="$VALUE" ;;
        make-and-model) NICKNAME="$VALUE" ;;
        device-id) ID="$VALUE" ;;
        natural_language) LANGUAGE="$VALUE" ;;
        *) echo "Ignoring key $KEY" 1>&2 ;;
   esac
done

# Output the last entry and a footer for YCP
Output
echo -e "  \$[]\n]"

# Remove the temporary files 
rm $TMP_DATA_RAW $TMP_DATA
echo 'Finished.' >>$PROGRESS
exit 0

