Smbspool replacement for CUPS: cups-smbspool-0.1

Problems and successes with specific brands/models of printers
Post Reply
Message
Author
User avatar
Patriot
Posts: 733
Joined: Thu 15 Jan 2009, 19:04

Smbspool replacement for CUPS: cups-smbspool-0.1

#1 Post by Patriot »

Hmmm .....

Recently, BarryK enquired about samba-tng's non-existent smbspool and whether printing through smbclient will work. I've advised him that it is indeed possible to do raw/postcript printing with smbclient and the smbc script (from http://willem.engen.nl/projects/cupssmb/) is what he can use or base upon.

I've taken a closer look at the whole smbspool thingy and have scribbled a drop-in replacement script for smbspool by sending print job(s) to smbclient. This script is loosely based on samba's smbspool internal logics, uses smbspool input parameter format and attempts to mimic smbspool behaviour. This script is designed to work with existing CUPS device URI.

The device URI (Uniform Resource Identifier) format for smbspool is defined as:
  • smb://[username[:password]@][workgroup/]server[:port]/printer
Please take note of the compulsory minimum in bold: smb:// [username[:password]@] [workgroup/] server [:port] /printer

Examples:
  • 1. smb://PRINTSERVER/HP4V (minimum parameter smb://server/printer)

    2. smb://192.168.1.2/ML1200 (same as #1 but using IP address)

    3. smb://zigbert:ladiesman217@/192.168.2.22:9191/MP250 (extended parameters with username, password and server port)

    4. smb://dogbert:majesty@SYHDP/DILBERT/LEDCOPIER (extended parameters with username, password and domain name)

Code: Select all

#!/bin/sh
# Patriot July 2010. GPLv2
# smbspool drop-in replacement script (via smbclient) for CUPS

# This software is not subject to any export provision of the United States
# Department of Commerce, and may be exported to any country or planet.

# Without parameters, assume a CUPS backend query
if [ -z "$1" ]; then
  echo 'network smb "Unknown" "Windows Printer via SAMBA (smbclient)"'
  exit 0
fi

function errmsg()
{
  echo -e "\nUsage: $0 [DEVICE_URI] job-id user title copies options [file]\n"
  echo -e "The DEVICE_URI environment variable contains the destination printer," >&2
  echo -e "smb://[username[:password]@][workgroup/]server[:port]/printer\n" >&2
  [ $1 -eq 0 ] && echo -e "Error: invalid parameter count" >&2
  [ $1 -eq 1 ] && echo -e "Error: malformed URI header" >&2
  [ $1 -eq 2 ] && echo -e "Error: malformed URI block" >&2
  exit 1
}

# Validate parameter count n, 5 =< n <= 6
[ -z "$5" -o "$7" ] && errmsg 0

# Validate DEVICE_URI header
[ "${DEVICE_URI:0:6}" != "smb://" ] && errmsg 1

# Validate DEVICE_URI block
pdev_uri_slash=$(echo $DEVICE_URI| tr -d "/")
let pdev_uri_wc=${#DEVICE_URI}-${#pdev_uri_slash}
[ $pdev_uri_wc -lt 3 -o $pdev_uri_wc -gt 4 ] && errmsg 2

# Retrieve parameters
job_id="$1"; user="$2"; title="$3"; copies="$4"; options="$5"; job_file="$6"

# Parse the DEVICE_URI
pdev_uri=${DEVICE_URI:6}
if [ $pdev_uri_wc -eq 4 ]; then
  # parse workgroup/domain
  pdev_upw=${pdev_uri%%/*}
  pdev_workgroup=${pdev_upw#*@}
  if [ ${#pdev_workgroup} -ne ${#pdev_upw} ]; then
	pdev_upw=${pdev_upw%@*}
  else
	pdev_upw=${pdev_upw%@}
	pdev_workgroup=
  fi

  # parse username/password
  username=${pdev_upw%:*}
  if [ ${#username} -eq ${#pdev_upw} ]; then
	password=""
  else
	password=${pdev_upw#*:}
  fi
  pdev_uri=${pdev_uri#*/}
fi

# parse server, port & printer
pdev_server=${pdev_uri%/*}
pdev_printer=${pdev_uri#*/}
pdev_port=${pdev_server#*:}
if [ ${#pdev_port} -eq ${#pdev_server} ]; then
  pdev_port=
else
  pdev_server=${pdev_server%:*}
fi

# Prep extra parameters
extra=
[ "$password" ] || extra="-N "
[ "$pdev_port" ] && extra="${extra}-P $pdev_port "
[ "$pdev_workgroup" ] && extra="${extra}-W $pdev_workgroup "

# Prep credentials
orgUSER=$USER
if [ "$username" ]; then
  export USER="$username"
else
  export USER="guest"
fi
if [ "$password" ]; then
  export PASSWD="$password"
fi

# Prep command set
cmd_set=""
if [ -z "$job_file" ]; then
  # assume printing from stdin
  pqdata="/tmp/smbrpd-$job_id.$title"
  cat > "$pqdata"
else
  pqdata="$job_file"
fi
for i in $(seq $copies)
do
  # Make copies ?
  cmd_set=$cmd_set'print "'$pqdata'" ;'
done

# TODO: Check printer connection online?

# Send the stuff through smbclient
PrnResult=$(smbclient "//$pdev_server/$pdev_printer" ${extra} -c "$cmd_set" 2>&1; echo -e "\nSMBEXIT=$?")

# Cleanups
export USER=$orgUSER
[ "$PASSWD" ] && unset PASSWD
[ -z "$job_file" -a -e "$pqdata" ] && rm -f "$pqdata"

# Set exit status for CUPS
exitStat=$(echo "$PrnResult" | grep 'SMBEXIT'); exitStat=${exitStat#*=}
if [ $exitStat -eq 0 ]; then
  echo "SUCCESS: $PrnResult" >&2
else
  echo "ERROR!: $PrnResult" >&2
  exit 2
fi
exit 0
Features:
- Fully supports smb URI format. This allows the authentication details to be embedded within the URI.
- Allows printing to multiple authenticated servers without mucking with separate authentication files.
- Supports print copies option, if required.
- Supports smbclient from both samba and samba-tng.

Manual installation:
1. Save the script as /usr/lib/cups/backend/smb.
2. Give it an owner only permission (# chmod 700 /usr/lib/cups/backend/smb). (If you skip this, smbclient will bork reading smb.conf file)
3. Configure smb printer if required & do a test print

Automatic installation:
1. Install the pet file. The script will be at /usr/lib/cups/backend.
2. Configure smb printer if required & do a test print

Final notes:
- This script is designed to run on puppy >= 4.0 platform with cups >= 1.1.x.
- Development and testing is done on puppy412 with cups-1.3.11, samba-3.0.37 and samba-tng-0.5rc1
- and yes, if anyone's wondering, I am able to print raw/ps using either samba or samba-tng smbclient.


Rgds

._.
Attachments
cups-smbspool-0.1.pet
smbspool backend replacement for CUPS &gt;= 1.1.x
(1.7 KiB) Downloaded 1000 times
Last edited by Patriot on Sun 11 Jul 2010, 13:10, edited 3 times in total.

User avatar
Patriot
Posts: 733
Joined: Thu 15 Jan 2009, 19:04

#2 Post by Patriot »

Here be dragons

User avatar
BarryK
Puppy Master
Posts: 9392
Joined: Mon 09 May 2005, 09:23
Location: Perth, Western Australia
Contact:

#3 Post by BarryK »

Great stuff!
This in now implemented in Woof:

http://bkhome.org/blog/?viewDetailed=01724
[url]https://bkhome.org/news/[/url]

Post Reply