-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathpharos
executable file
·174 lines (157 loc) · 5.93 KB
/
pharos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#!/usr/bin/python2
# Script Name: pharos
# Script Function:
# This is a CUPS backend for the Pharos Remote Printing LPD Server.
# Save this file in your CUPS backend directory, usually
# /usr/lib/cups/backend/ or /usr/local/lib/cups/backend/ or /usr/libexec/cups/backend/
#
# Mark this filter world-readable and world-executable. Restart CUPS to
# make the new backend known to the spooler.
#
# See http://www.openprinting.org/cups-doc.html and the additional
# instructions below.
#
# Usage:
#
# cp pharos /usr/lib/cups/backend/
# chmod 755 /usr/lib/cups/backend/pharos
# killall -HUP cupsd (or "/etc/init.d/cups restart")
# lpadmin -p <queue name> -E -v pharos://<print server address>/<print queue>
#
# with
# <print server address>: The DNS name or IP address of the print server
# <print queue>: The name of the LPD queue on the print server
# Example URIs:
# pharos://printserver.university.edu/HP_LaserJet
#
# This will print to a Pharos Uniprint Print server with DNS name printserver.university.edu and print queue HP_LaserJet
#
# Author: Junaid Ali
# Version: 1.0
__version__ = '1.0'
__title__ = 'CUPS backend for Pharos Remote Printing'
__doc__ = 'CUPS backend for popup based printing to Pharos LPD server'
# Imports ============================================
import sys
import os
import socket
import ConfigParser
import os
import logging
import logging.config
import tempfile
import subprocess
import re
# CUPS backend return codes =========================
CUPS_BACKEND_OK = 0
CUPS_BACKEND_FAILED = 1
CUPS_BACKEND_AUTH_REQUIRED = 2
CUPS_BACKEND_HOLD = 3
CUPS_BACKEND_STOP = 4
CUPS_BACKEND_CANCEL = 5
# Script Variables ===================================
programConfigFilePath = '/usr/local/etc/pharos.conf'
cupsBackendDIR = '/usr/lib/cups/backend'
if not os.path.isdir(cupsBackendDIR):
cupsBackendDIR = '/usr/libexec/cups/backend'
# Function Declaration ===============================
def main():
"""
The main function of the script
"""
if len(sys.argv) == 1:
# Without arguments display backend info
sys.stdout.write("network %s \"Unknown\" \"%s\" \n" %(os.path.basename(sys.argv[0]), __doc__))
sys.stdout.flush()
sys.exit(CUPS_BACKEND_OK)
if len(sys.argv) not in (6,7):
sys.stdout.write("Usage: %s job-id user title copies options [file]\n" % os.path.basename(sys.argv[0]))
sys.stdout.flush()
logger.error("Wrong number of arguments (%d). Usage %s job-id user" %(len(sys.argv[0]), sys.argv[0]))
sys.exit(CUPS_BACKEND_OK)
# Try to get print job parameters from user
host = ''
if os.path.exists(programConfigFilePath):
logger.info('calculating port information using %s' %programConfigFilePath)
config = ConfigParser.ConfigParser()
config.read(programConfigFilePath)
port = config.getint("popupserver", "port")
logger.info('Setting up the server connection port to %d' %port)
else:
port = 50000
logger.info('Trying to connect to host %s on port %d' %(host, port))
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
except socket.error, (value, message):
if s:
s.close()
logger.error('Could not connect to popup server. Error %s' %message)
sys.exit(CUPS_BACKEND_FAILED)
s.send('GetPrintJobParameters')
data = s.recv(1024)
s.close()
logger.info('Received response = %s' %data)
# Split response
responseParts = data.split(',')
printjobparams = {}
for part in responseParts:
peices = part.split(':')
if len(peices) == 2:
printjobparams[peices[0].strip()] = peices[1].strip()
logger.info('Response dictionary = %s' %printjobparams)
logger.info('User ID received = %s' %printjobparams["userid"])
logger.info('Print Command received = %s' %printjobparams["printjob"])
# Calculate actual LPD queue DEVICE URI
logger.info('Processing DEVICE_URI')
deviceURI = os.environ['DEVICE_URI']
devParts = deviceURI.split(':')[1].split('/')
deviceURI = 'lpd://' + devParts[len(devParts)-2] + '/' + devParts[len(devParts)-1]
logger.info('lpd print queue uri = %s' % deviceURI )
os.environ['DEVICE_URI'] = deviceURI
logger.info('Set DEVICE_URI to %s' % os.environ['DEVICE_URI'])
# Check input arguments
jobID = sys.argv[1]
userName = sys.argv[2]
jobTitle = sys.argv[3]
copies = sys.argv[4]
printOptions = sys.argv[5]
if len(sys.argv) > 6:
logger.info('using printFile %s' %sys.argv[6])
printFile = sys.argv[6]
else:
# Create print file from STDIN
logger.info('printFile argument not supplied, will create it using STDIN')
printFileTuple = tempfile.mkstemp()
printFile = printFileTuple[1]
printFileHndl = open(printFile, 'wb')
for line in sys.stdin:
printFileHndl.writelines(line)
printFileHndl.close()
# check if continue printing
if not printjobparams["printjob"] == "yes":
logger.info("User chose to cancel job. Exiting")
if os.path.exists(printFile):
os.unlink(printFile)
sys.exit(CUPS_BACKEND_CANCEL)
logger.info('Job Arguments (Job ID: %s, User Name: %s, Job Title: %s, Copies: %s, Print Options: %s, Print File: %s)' %(jobID, userName, jobTitle, copies, printOptions, printFile))
command = [os.path.join(cupsBackendDIR, 'lpd'), jobID, printjobparams["userid"], jobTitle, copies, printOptions, printFile]
logger.info("Running Command with pipe separated arguments: " + "|".join(command))
returnCode = subprocess.call(command)
logger.info('Command return code = %d' %(returnCode))
# Delete the temp file used
if os.path.exists(printFile):
os.remove(printFile)
logger.info('Successfully removed print file: %s' %(printFile))
# Terminate gracefully and return the code from lpd printing
logger.info('Printing completed')
sys.exit(returnCode)
# Main Script ========================================
try:
logging.config.fileConfig(programConfigFilePath)
logger = logging.getLogger('pharos')
except (TypeError, ConfigParser.NoSectionError):
syslog.syslog(syslog.LOG_ERR, '%s could not instantiate logging using config file %s. Exiting' %(sys.argv[0], programConfigFilePath))
sys.exit(CUPS_BACKEND_STOP)
if __name__ == "__main__":
main()