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.
227 lines
5.8 KiB
Bash
227 lines
5.8 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 and copy PPD file if exists
|
|
systemctl stop cups
|
|
cat ${TEMP_CONF_FILE} >> /etc/cups/printers.conf
|
|
if [ -f "/etc/cups/ppd/${PRINTER}.ppd" ]; then
|
|
cp "/etc/cups/ppd/${PRINTER}.ppd" "/etc/cups/ppd/${PRINTER}_duplicate.ppd"
|
|
else
|
|
echo "Info: No printer definition file copied"
|
|
fi
|
|
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 '[ \/'\''"?#]' <<< "${NEW_NAME}"; then
|
|
echo "Invalid characters in new name '${NEW_NAME}'!"
|
|
echo "Valid characters are anything except \" ' \\ / ? # and spaces"
|
|
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
|
|
if [ -f "/etc/cups/ppd/${PRINTER}.ppd" ]; then
|
|
mv "/etc/cups/ppd/${PRINTER}.ppd" "/etc/cups/ppd/${NEW_NAME}.ppd"
|
|
else
|
|
echo "Info: No printer definition file moved"
|
|
fi
|
|
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
|