/[cvs]/lpr-agent/lpr-agent
ViewVC logotype

Annotation of /lpr-agent/lpr-agent

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (hide annotations) (vendor branch)
Fri Jun 6 05:12:18 2003 UTC (20 years, 11 months ago) by teddy
Branch: teddy
CVS Tags: lpr-agent-1_0, start
Changes since 1.1: +0 -0 lines
First import

1 teddy 1.1 #!/usr/bin/python
2     #
3     # lpr-agent - keep a password in memory and use it to print stuff
4     # Copyright (C) 2000 Teddy Hogeborn
5     #
6     # This program is free software; you can redistribute it and/or modify
7     # it under the terms of the GNU General Public License as published by
8     # the Free Software Foundation; either version 2 of the License, or
9     # (at your option) any later version.
10     #
11     # This program is distributed in the hope that it will be useful,
12     # but WITHOUT ANY WARRANTY; without even the implied warranty of
13     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     # GNU General Public License for more details.
15     #
16     # You should have received a copy of the GNU General Public License
17     # along with this program; if not, write to the Free Software
18     # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     #
20     # Author: Teddy Hogeborn <teddy@fukt.hk-r.se>
21     # Folkparksv. 22
22     # 372 38 Ronneby
23     # SWEDEN
24    
25     import os, errno, tempfile, sys, getopt, SocketServer, rfc822, string
26     from socket import *
27     from signal import *
28    
29     # Parse the command line options and set the "c_flag" accordingly
30     optlist, args = getopt.getopt(sys.argv[1:], 'bck', ['sh', 'bourne-shell',\
31     'csh', 'c-shell',\
32     'debug', 'kill', \
33     'version', 'help'])
34    
35     if ('--version', '') in optlist:
36     print """lpr-agent (lpr-agent) 1.0
37     Copyright (C) 2000 Teddy Hogeborn
38     lpr-agent comes with ABSOLUTELY NO WARRANTY.
39     You may redistribute copies of lpr-agent under the terms of the GNU
40     General Public License. For more information about these matters, see
41     the file named COPYING."""
42     sys.exit(0)
43    
44     if ('--help', '') in optlist:
45     print """lpr-agent prints some shell commands to be evaluated and also forks
46     off and stays in memory, receiving commands and data on a Unix file
47     system socket. It can then be accessed with the program "lpr-client".
48    
49     Usage: lpr-agent [options]
50    
51     Examples of common usage:
52     Start a server and evaluate commands
53     eval `lpr-agent`
54     Start a server and evaluate commands suitable for C-shells
55     eval `lpr-agent --c-shell`
56     Kill the agent (when logging out or when not printing anymore):
57     lpr-agent --kill
58    
59     Normal options:
60     -k, --kill kill the agent
61     -b, --sh, --bourne-shell print commands suitable for
62     bourne shells
63     -c, --csh, --c-shell print commands suitable for
64     c-shells
65     --version show version number
66     --help show this help
67    
68     Obscure or debugging options:
69     --debug do not close stdout and stderr,
70     show debugging information on
71     stdout and lets any Python
72     errors show up on stderr
73    
74     Report bugs to <teddy@fukt.hk-r.se>.
75     """
76     sys.exit(0)
77    
78     debug_flag = ('--debug', '') in optlist
79    
80     c_flag = (('-c', '') in optlist) or (('--csh', '') in optlist)\
81     or (('--c-shell', '') in optlist)
82    
83     if (('-k', '') in optlist or ('--kill', '') in optlist):
84     if os.environ.has_key('LPR_AGENT_PID'):
85     try:
86     os.kill(string.atoi(os.environ['LPR_AGENT_PID']), SIGTERM)
87     except os.error, the_error:
88     if the_error[0] != errno.ESRCH:
89     raise os.error, the_error
90     else:
91     print "The agent is not running."
92     sys.exit(1)
93     else:
94     print "No agent is running."
95     sys.exit(1)
96     sys.exit(0)
97    
98     # Make up a name for the directory.
99     if os.environ.has_key('TMPDIR'):
100     tempfile.template=os.environ['TMPDIR']
101     else:
102     tempfile.tempdir="/tmp"
103     tempfile.template="lpr-" + `os.getpid()` + "-"
104     socket_dir=tempfile.mktemp()
105    
106     # Try and create the directory, but don't fail if it already exists.
107     try:
108     os.mkdir(socket_dir, 0700)
109     except os.error, the_error:
110     if the_error[0] != errno.EEXIST:
111     raise os.error, the_error
112     else:
113     # If the directory alread exists we should be able to change
114     # the permissions on it. If we can't, the directory is owned
115     # by someone else who is trying to fool us into using it.
116     os.chmod(socket_dir, 0700)
117    
118     # Make up a name for the file/socket.
119     tempfile.tempdir=socket_dir
120     tempfile.template="agent." + `os.getpid()` + "-"
121     socket_name=tempfile.mktemp()
122    
123     def cleanup_socket():
124     "Close socket, remove file and directory; called on exit."
125     try:
126     sock.shutdown(2)
127     except os.error, the_error:
128     pass
129     try:
130     os.remove(socket_name)
131     except os.error, the_error:
132     pass
133     try:
134     os.rmdir(socket_dir)
135     except os.error, the_error:
136     pass
137    
138     # Try and create an unnamed socket. If we fail we call the cleanup
139     # function to remove the directory and then call the default error
140     # handler, which should abort. (The file/socket hasn't been created
141     # yet.)
142     try:
143     sock = socket(AF_UNIX, SOCK_STREAM)
144     except os.error, the_error:
145     cleanup_socket()
146     raise os.error, the_error
147    
148     # Fork off a child daemon process; In the parent, just print some
149     # commands to be eval'ed by a shell and then exit.
150     pid=os.fork()
151     if pid != 0:
152     if c_flag:
153     print "setenv LPR_AUTH_SOCK " + socket_name + ";"
154     print "setenv LPR_AGENT_PID " + `pid` + ";"
155     print "echo Agent pid " + `pid` + ";"
156     else:
157     print "LPR_AUTH_SOCK=" + socket_name + "; export LPR_AUTH_SOCK;"
158     print "LPR_AGENT_PID=" + `pid` + "; export LPR_AGENT_PID;"
159     print "echo Agent pid " + `pid` + ";"
160     sys.exit(0)
161    
162     # We want to become a daemon now.
163    
164     # Close all standard open file descriptors
165     #sys.stdin.close()
166     null=os.open("/dev/null", os.O_NOCTTY | os.O_RDONLY)
167     os.dup2(null, sys.stdin.fileno())
168     os.close(null)
169     if not debug_flag:
170     # sys.stdout.close()
171     # sys.stderr.close()
172     null=os.open("/dev/null", os.O_NOCTTY | os.O_WRONLY)
173     os.dup2(null, sys.stdout.fileno())
174     os.dup2(null, sys.stderr.fileno())
175     os.close(null)
176    
177     # Create a new process group for this process
178     os.setsid()
179    
180     # On exit remove the socket and the directory
181     sys.exitfunc=cleanup_socket
182    
183     signal(SIGINT, SIG_IGN)
184    
185     signal(SIGHUP, lambda signum, frame: sys.exit(0))
186     signal(SIGTERM, lambda signum, frame: sys.exit(0))
187    
188     # OK, we're a real daemon now.
189    
190     BUFSIZE=8192
191    
192     def stripcrnl(string):
193     "Return STRING with any CR or NL stripped off the end."
194     result = ""
195     if string[-1:] == '\n' or string[-1:] == '\r':
196     result = string[:-1]
197     if result[-1:] == '\n' or result[-1:] == '\r':
198     return result[:-1]
199     else:
200     return result
201    
202     # Inherit a handler class to handle every connection.
203     class connectionhandler(SocketServer.BaseRequestHandler):
204     def handle(self):
205     if debug_flag:
206     print sys.argv[0] + ": server handling connection"
207     clientdata = os.fdopen(self.request.fileno(), "rb")
208     # Read first line; it has the command on it.
209     command = clientdata.readline()
210     command = stripcrnl(command)
211     if debug_flag:
212     print sys.argv[0] + ": ServerCommand: " + command
213     # Read headers, if any.
214     message = rfc822.Message(clientdata, 0)
215     if debug_flag:
216     print sys.argv[0] + ": Server EOH"
217     # Do stuff depending on command.
218     if command == "debug":
219     # Debug command, just print all the input to stdout.
220     # This is only of any use if the agent is running with
221     # --debug, i.e., has not closed stdout.
222     if debug_flag:
223     print sys.argv[0] + ": Server command: debug"
224     if debug_flag:
225     # print "password: " + agent.password
226     while 1:
227     data = clientdata.read(BUFSIZE)
228     if not data: break
229     if debug_flag:
230     sys.stdout.write(data)
231     elif command == "print":
232     # Print command, pipe the input to smbclient.
233     if debug_flag:
234     print sys.argv[0] + ": server command: print"
235     smbclientformat = "smbclient \"%s\" \"%s\" -N -P %s %s -c \"%s\""
236     # service, passwd, ip, options, command
237     smbserver = "obelix"
238     smbprinter = "rby_4"
239     smbservice = None
240     smbserverip = "-I obelix.rby.hk-r.se"
241     smbclientoptions = ""
242     smbclientcommand = "printmode graphics;print -"
243     if message.getheader('SmbClientFormat'):
244     smbclientformat = message.getheader('SmbClientFormat')
245     if message.getheader('SmbServer'):
246     smbserverip = ""
247     smbserver = message.getheader('SmbServer')
248     if message.getheader('SmbPrinter'):
249     smbprinter = message.getheader('SmbPrinter')
250     if message.getheader('SmbService'):
251     smbserver = None
252     smbprinter = None
253     smbclientip = ""
254     smbservice = message.getheader('SmbService')
255     if message.getheader('SmbServerIP'):
256     smbserverip = "-I \"" \
257     + message.getheader('SmbServerIP')\
258     + "\""
259     if message.getheader('SmbClientOptions'):
260     smbclientoptions = message.getheader('SmbClientOptions')
261     if message.getheader('SmbClientCommand'):
262     smbclientcommand = message.getheader('SmbClientCommand')
263     # If it wasn't explicitly set, set the service from the
264     # components, default or otherwise.
265     if not smbservice:
266     smbservice = "//%s/%s" % (smbserver, smbprinter)
267     pipecmd = smbclientformat % (smbservice,\
268     agent.password, \
269     smbserverip, \
270     smbclientoptions, \
271     smbclientcommand)
272     pipe = None
273     pipe = os.popen(pipecmd, "w")
274     if debug_flag:
275     print sys.argv[0] + ": Pipecmd: " + pipecmd
276     while 1:
277     data = clientdata.read(BUFSIZE)
278     if not data: break
279     if debug_flag:
280     sys.stdout.write(data)
281     else:
282     pipe.write(data)
283     #if not debug_flag:
284     pipe.close()
285     elif command == "write":
286     # Write command, write input to file specified in header.
287     # Used for testing.
288     if debug_flag:
289     print sys.argv[0] + ": server command: write"
290     outfile = open(message.getheader('Filename'), "wb")
291     while 1:
292     data = clientdata.read(BUFSIZE)
293     if not data: break
294     outfile.write(data)
295     outfile.close()
296     elif command == "password":
297     # Set password variable.
298     if debug_flag:
299     print sys.argv[0] + ": server command: password"
300     password = clientdata.readline(80)
301     agent.password = stripcrnl(password)
302     del password
303     elif command == "eval":
304     # Eval all input. May be used for extension and
305     # modification of already running agents.
306     if debug_flag:
307     print sys.argv[0] + ": server command: eval"
308     while 1:
309     line = clientdata.readline()
310     if not line: break
311     eval(line)
312     elif command == "quit":
313     clientdata.close()
314     self.request.close()
315     cleanup_socket()
316     os._exit(0)
317     else:
318     if debug_flag:
319     print sys.argv[0] + ": Unknown command '" + command + "'"
320     clientdata.close()
321     self.request.close()
322    
323     ## Inherit a server agent class.
324     # class LPRAgent(ForkingMixIn, SocketServer.UnixStreamServer): pass
325     class LPRAgent(SocketServer.UnixStreamServer):
326     password = ""
327    
328     # Instantiate an agent to listen on the socket and call the handler.
329     agent = LPRAgent(socket_name, connectionhandler)
330    
331     if debug_flag:
332     print sys.argv[0] + ": Server starting..."
333    
334     # Go go go!
335     agent.serve_forever()

root@recompile.se
ViewVC Help
Powered by ViewVC 1.1.26