You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
5.4 KiB
Bash

#!/bin/bash
set -e
function usage {
echo "Script usage:"
echo ""
echo "${0} list Lists all printers"
echo "${0} duplicate <printer-name> Duplicates a printer"
echo "${0} dup <printer-name> Alias of 'duplicate'"
echo "${0} rename <printer-name> <new-name> Renames a printer internally"
echo "${0} ren <printer-name> <new-name> Alias of 'rename'"
echo "${0} clear-queue <printer-name> Clears the current queue of a printer"
echo "${0} cq <printer-name> Alias of 'clear-queue'"
}
##
# Ensures the 'uuid' command is installed
##
function ensure_uuid_command {
if ! which uuid >/dev/null; then
echo "Installing required 'uuid' package via apt-get..."
DEBIAN_FRONTEND=noninteractive apt-get install -q --yes uuid >/dev/null
echo "OK"
fi
}
##
# Lists all internal names of available printers
#
# @echo List of all available printers
##
function list {
echo "Available printers:"
lpstat -v | awk '!/ iserv:/{ gsub(":", "", $3); print $3 }'
}
##
# Creates a duplicate of an existing printer
#
# @param $1 Internal name of the printer
##
function printer_duplicate {
ensure_uuid_command
PRINTER=${1}
echo "Duplicating printer '${PRINTER}'..."
if [ "${PRINTER}" = "" ]; then
echo "No printer specified!"
exit 1
elif [ "${PRINTER}" = "iserv" ]; then
echo "IServ built-in printer 'iserv' cannot be duplicated!"
exit 1
fi
TEMP_CONF_FILE=$(mktemp)
sed -n '/<Printer '${PRINTER}'>/,/<\/Printer>/p' /etc/cups/printers.conf > ${TEMP_CONF_FILE}
if (( $(stat --printf="%s" ${TEMP_CONF_FILE}) == 0 )); then
echo "Printer not found!"
rm ${TEMP_CONF_FILE}
exit 1
fi
NEXT_ID=$(next_printer_id)
# Set printer ID
sed -i 's/^PrinterId [0-9]\+/PrinterId '${NEXT_ID}'/' ${TEMP_CONF_FILE}
# Change printer UUID
sed -i 's/^UUID urn:uuid:.\+$/UUID urn:uuid:'$(uuid)'/' ${TEMP_CONF_FILE}
# Append '_duplicate' to printer name
sed -i 's/^<Printer \(.\+\)>$/<Printer \1_duplicate>/' ${TEMP_CONF_FILE}
# Update printer description
sed -i 's/^Info \(.\+\),/Info Duplicate of \1,/' ${TEMP_CONF_FILE}
# Change ConfigTime to now
sed -i 's/^ConfigTime [0-9]\+/ConfigTime '$(date +%s)'/' ${TEMP_CONF_FILE}
# Change StateTime to now
sed -i 's/^StateTime [0-9]\+/StateTime '$(date +%s)'/' ${TEMP_CONF_FILE}
# Set printer state to idle
sed -i 's/^State .\+$/State Idle/' ${TEMP_CONF_FILE}
sed -i 's/^StateMessage .\+$//' ${TEMP_CONF_FILE}
sed -i 's/^Reason .\+$//' ${TEMP_CONF_FILE}
# Add new configuration to CUPS
systemctl stop cups
cat ${TEMP_CONF_FILE} >> /etc/cups/printers.conf
systemctl start cups
rm "${TEMP_CONF_FILE}"
echo "OK"
}
##
# Renames a printer internally
#
# @param $1 Current internal name of the printer
# @param $2 New internal name of the printer
##
function printer_rename {
PRINTER=${1}
NEW_NAME=${2}
echo "Renaming printer '${PRINTER}' to '${NEW_NAME}'..."
if [ "${PRINTER}" = "" ]; then
echo "No printer specified!"
exit 1
elif [ "${NEW_NAME}" = "" ]; then
echo "No new name specified!"
exit 1
elif [ "${PRINTER}" = "iserv" ]; then
echo "IServ built-in printer 'iserv' cannot be renamed!"
exit 1
fi
if ! grep -qE '^[a-zA-Z0-9_]+$' <<< "${NEW_NAME}"; then
echo "Invalid characters in new name '${NEW_NAME}'!"
echo "Valid characters are: A-Z a-z 0-9 _"
exit 1
fi
if ! grep -qE "^<Printer ${PRINTER}>" /etc/cups/printers.conf; then
echo "Printer not found!"
exit 1
fi
echo "Renaming the printer will drop all current pages in the queue!"
echo -n "Continue <y/n>? "
read CHOICE
if [ "${CHOICE}" != "y" ]; then
echo "Operation cancelled"
exit 1
fi
cp /etc/cups/printers.conf /etc/cups/printers.conf.ren_bak
# Stop CUPS, rename, restart CUPS
systemctl stop cups
sed -i 's/<Printer '${PRINTER}'>$/<Printer '${NEW_NAME}'>/' /etc/cups/printers.conf
systemctl start cups
echo "OK"
}
##
# Clears the printing queue of a printer
#
# @param $1 Internal name of the printer
##
function printer_clear_queue {
PRINTER=${1}
echo "Clearing printing queue of '${PRINTER}'..."
if [ "${PRINTER}" = "" ]; then
echo "No printer specified!"
exit 1
fi
if ! lpstat -e | grep -q "${PRINTER}"; then
echo "Printer not found!"
exit 1
fi
lprm -P "${PRINTER}" -
echo "OK"
}
##
# Fetches the next free printer ID
#
# @echo Next available printer ID
##
function next_printer_id {
HIGHEST_ID=-1
while read LINE; do
if grep -qE "^PrinterId" <<< "${LINE}"; then
PRINTER_ID=$(awk '/PrinterId/{ print $2 }' <<< "${LINE}")
if (( PRINTER_ID > HIGHEST_ID )); then
HIGHEST_ID=${PRINTER_ID}
fi
fi
done < /etc/cups/printers.conf
(( HIGHEST_ID++ ))
echo ${HIGHEST_ID}
}
case "$1" in
duplicate|dup)
shift
printer_duplicate $@
;;
rename|ren)
shift
printer_rename $@
;;
clear-queue|cq)
shift
printer_clear_queue $@
;;
list)
list
;;
*)
usage
exit 1
;;
esac