root / pykota / trunk / bin / pkmail @ 2344

Revision 2344, 5.9 kB (checked in by jerome, 19 years ago)

Moved the GPL blurb into a single location.
Now uses named parameters in commands' help.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#! /usr/bin/env python
2# -*- coding: ISO-8859-15 -*-
3
4# An email gateway for PyKota
5#
6# PyKota - Print Quotas for CUPS and LPRng
7#
8# (c) 2003, 2004, 2005 Jerome Alet <alet@librelogiciel.com>
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22#
23# $Id$
24#
25#
26
27import sys
28import os
29import popen2
30import smtplib
31import email
32
33from pykota.tool import PyKotaTool, PyKotaToolError, crashed, N_
34from pykota.pdlanalyzer import PDLAnalyzer, PDLAnalyzerError
35
36__doc__ = N_("""pkmail v%(__version__)s (c) %(__years__)s %(__author__)s
37
38Email gateway for PyKota.
39
40command line usage :
41
42  pkmail  [options]
43
44options :
45
46  -v | --version       Prints pkmail's version number then exits.
47  -h | --help          Prints this message then exits.
48 
49   
50  This command is meant to be used from your mail server's aliases file,
51  as a pipe. It will then accept commands send to it in email messages,
52  and will send the answer to the command's originator.
53 
54  To use this command, create an email alias in /etc/aliases with
55  the following format :
56 
57    pykotacmd: "|/usr/bin/pkmail"
58   
59  Then run the 'newaliases' command to regenerate the aliases database.
60 
61  You can now send commands by email to 'pykotacmd@yourdomain.com', with
62  the command in the subject.
63 
64  List of supported commands :
65 
66        report [username]
67 
68  NB : For pkmail to work correctly, you may have to put the 'mail'
69  system user in the 'pykota' system group to ensure this user can
70  read the /etc/pykota/pykotadmin.conf file, and restart your
71  mail server (e.g. /etc/init.d/exim restart). It is strongly advised
72  that you think at least twice before doing this though.
73 
74  Use at your own risk !
75""")
76       
77       
78class PKMail(PyKotaTool) :       
79    """A class for pkmail."""
80    def main(self, files, options) :
81        """Accepts commands passed in an email message."""
82        data = sys.stdin.read()
83        message = email.message_from_string(data)
84        useremail = message["From"]
85        whoami = message["To"]
86        cmdargs = message["Subject"].split()
87        try :
88            (command, arguments) = (cmdargs[0].capitalize(), cmdargs[1:])
89        except IndexError :   
90            raise PyKotaToolError, "No command found !"
91       
92        badchars = """/<>&"'#!%*$,;\\"""
93        cheatmeonce = 0
94        for c in "".join(arguments) :
95            if c in badchars :
96                cheatmeonce = 1
97           
98        if cheatmeonce :   
99            self.logdebug("Possible intruder at %s : %s" % (useremail, str(arguments)))
100            result = "Either you mistyped your command, or you're a bad guy !"
101        else :
102            self.logdebug("Launching internal command '%s' with arguments %s" % (command, str(arguments)))
103            cmdfunc = getattr(self, "cmd%s" % command, self.cmdDefault)
104            result = cmdfunc(arguments)
105       
106        self.logdebug("Sending answer to : %s" % useremail)
107        server = smtplib.SMTP(self.smtpserver)
108        server.sendmail(whoami, [ useremail ], "From: %s\nTo: %s\nSubject: Result of your commands\n\n%s\n" % (whoami, useremail, result))
109        server.quit()
110        self.logdebug("Answer sent to : %s" % useremail)
111       
112        return 0
113       
114    def runCommand(self, cmd) :   
115        """Executes a command."""
116        self.logdebug("Launching : '%s'" % cmd)
117        os.environ["PATH"] = "%s:/bin:/usr/bin:/usr/local/bin:/opt/bin:/sbin:/usr/sbin" % os.environ.get("PATH", "")
118        child = popen2.Popen3(cmd)
119        child.tochild.close()
120        result = child.fromchild.read()
121        status = child.wait()
122        if os.WIFEXITED(status) :
123            status = os.WEXITSTATUS(status)
124        self.logdebug("'%s' exited with status %s" % (cmd, status))
125        return result
126       
127    def cmdDefault(self, arguments) :   
128        """Default command : sends an 'unknown command' message."""
129        return "Unknown command."
130       
131    def cmdReport(self, args) :   
132        """Generates a print quota report."""
133        return self.runCommand("repykota %s" % ' '.join([ '"%s"' % a for a in args ]))
134           
135if __name__ == "__main__" : 
136    retcode = 0
137    try :
138        defaults = { \
139                   }
140        short_options = "vh"
141        long_options = ["help", "version"]
142       
143        # Initializes the command line tool
144        mailparser = PKMail(doc=__doc__)
145        mailparser.deferredInit()
146       
147        # parse and checks the command line
148        (options, args) = mailparser.parseCommandline(sys.argv[1:], short_options, long_options, allownothing=1)
149       
150        # sets long options
151        options["help"] = options["h"] or options["help"]
152        options["version"] = options["v"] or options["version"]
153       
154        if options["help"] :
155            mailparser.display_usage_and_quit()
156        elif options["version"] :
157            mailparser.display_version_and_quit()
158        else :
159            retcode = mailparser.main(args, options)
160    except KeyboardInterrupt :       
161        sys.stderr.write("\nInterrupted with Ctrl+C !\n")
162    except SystemExit :       
163        pass
164    except :
165        try :
166            mailparser.crashed("pkmail failed")
167        except :   
168            crashed("pkmail failed")
169        retcode = -1
170
171    try :
172        mailparser.storage.close()
173    except (TypeError, NameError, AttributeError) :   
174        pass
175       
176    sys.exit(retcode)   
Note: See TracBrowser for help on using the browser.