root / pykota / trunk / bin / pkmail @ 2103

Revision 2091, 6.8 kB (checked in by jalet, 20 years ago)

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