Index: /emailtotracscript/trunk/AUTHORS
===================================================================
--- /emailtotracscript/trunk/AUTHORS	(revision 13)
+++ /emailtotracscript/trunk/AUTHORS	(revision 13)
@@ -0,0 +1,7 @@
+The email2trac package is written by:
+  Bas van der Vlies <basv@sara.nl>
+  Walter de Jong <walter@sara.nl>
+
+
+Initial setup and ideas from:
+  Daniel Lundin <daniel@edgewall.com>
Index: /emailtotracscript/trunk/COPYING
===================================================================
--- /emailtotracscript/trunk/COPYING	(revision 13)
+++ /emailtotracscript/trunk/COPYING	(revision 13)
@@ -0,0 +1,345 @@
+ GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+Copyright (C) <year> <name of author>
+
+This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: /emailtotracscript/trunk/Changelog
===================================================================
--- /emailtotracscript/trunk/Changelog	(revision 13)
+++ /emailtotracscript/trunk/Changelog	(revision 13)
@@ -0,0 +1,67 @@
+2006-01-04  Bas van der Vlies <basv@sara.nl>:
+
+	* Fixed getopt for -f option
+	* Added suppport for different TRAC versions (0.8 and 0.9)
+
+2006-01-03  Michel Jouvin  <jouvin@lal.in2p3.fr>
+
+	* email2trac.py (ReadConfig) : allow project name relative to project root in configuration file
+	
+	* email2trac.py (TicketEmailParser.parse): save entire email for debugging only if debug >= 2
+
+	* run_email2trac.c: pass wrapper arguments to Python script, filtering out --file 
+
+	* email2trac.py (TicketEmailParser.debug_attachments): set tmp file created for debugging writable by anybody (to avoid problem if the script is run with a different uid during tests)
+
+	* email2trac.py (TicketEmailParser.parse): set tmp file created for debugging writable by anybody (to avoid problem if the script is run with a different uid during tests)
+
+2005-12-22  Michel Jouvin  <jouvin@lal.in2p3.fr>
+
+	* Makefile: add a Makefile to build and install email2trac
+
+	* email2trac.py: migrate to Trac 0.9 API
+
+2005-12-21  Michel Jouvin  <jouvin@lal.in2p3.fr>
+
+	* run_email2trac.c: add error messages if DEBUG macro defined
+
+	* run_email2trac.c: add error testing and specific return values for each error
+
+	* run_email2trac.c: Move site specific paramaters to run_email2trac.h
+
+	* run_email2trac.h: include file to define site specific paramaters
+
+0.2.4 01/11/2005
+	Added email_header option if set then show TO/CC fields in
+	description of the ticket.
+
+	Fixed an error in the mailto URL. This was an old error that 
+	supposed to be fixed but reoccured in this version.
+	
+0.2.3 31/10/2005
+	Fixed a bug with base64 encoded attachments/emails
+	Fixed by: Walter de Jong
+
+0.2.2 10/10/2005
+	according to RFC 2368 (titled "the mailto URL scheme") the mailto
+	URL can only work with short &body messages. It fails with long
+	messages and the link won't work. Therefore the mail body is
+	no longer copied into the mail reply.
+
+0.2.1 10/07/2005
+	body of reply email looks better
+
+
+0.2   10/07/2005
+	mailto is replaced by a html mailto to line. If 
+	you reply to the ticket via this link then an 
+	email client is started with some default values:
+		To: <reporter>
+		Subject: Re: <orginal subject>
+		Body: email_comment <orginal text>
+
+	email2trac.conf:
+		email_comment: # (default:  >)
+
+		
+
Index: /emailtotracscript/trunk/INSTALL
===================================================================
--- /emailtotracscript/trunk/INSTALL	(revision 13)
+++ /emailtotracscript/trunk/INSTALL	(revision 13)
@@ -0,0 +1,38 @@
+The email2trac package contains the following utilities:
+ - email2trac.py:
+    Converts an email to ticket. Reads a config file email2trac.conf
+ - run_email2trac.c:
+    Suid program that changes the MTA-user to the TRAC-user so that we can 
+    save attachments
+ - delete_spam.py:
+    A small program that deletes the SPAM tickets from the database
+ - email2trac.conf:
+    Is read by email2trac.py to set the various options. This are the options:
+    [DEFAULT]               # REQUIRED
+    project: /data/trac/bas # REQUIRED
+    debug: 1                # OPTIONAL, if set print some DEBUG info 
+    spam_level: 4           # OPTIONAL, if set check for SPAM mail 
+    reply_address: 1        # OPTIONAL, if set then fill in ticket CC field
+    umask: 022              # OPTIONAL, Use this umask for saving attachments
+    mailto_link: 1          # OPTIONAL, if set then [mailto:<CC>] in description
+    email_header: 1         # OPTIONAL, if set then show TO/CC fields in description
+    trac_version: 0.8	    # OPTIONAL, if set use this as trac version
+
+
+SETUP
+=====
+
+It depends on your MTA how the setup is. Below is an example of the SARA setup
+that uses postfix as our MTA.  
+  - Edit Makefile, adjust the variables
+  - make
+  - make install
+  - Copy email2trac.conf to /etc  (default location for email2trac.py)
+    If different location use the "-f <config file> or --file=<config file>" to run_email2trac
+
+  - vi /etc/aliases
+     bas: |/usr/sbin/run_email2trac [-f <config file>| --file=<config file>]
+
+  - newaliases
+  - Test
+     mail bas < test7.eml
Index: /emailtotracscript/trunk/Makefile
===================================================================
--- /emailtotracscript/trunk/Makefile	(revision 13)
+++ /emailtotracscript/trunk/Makefile	(revision 13)
@@ -0,0 +1,41 @@
+# email2trac Makefile
+#
+# defaullt values are:
+#
+# MTA_USER "nobody"
+# TRAC_USER "www-data"
+# TRAC_SCRIPT_NAME "email2trac.py"
+#
+#MTA_USER=daemon
+#TRAC_USER=apache
+#TRAC_SCRIPT_NAME=email2trac.py
+#INSTALL_DIR=/www/Web/servers/trac/site-config/scripts
+#PYTHON_BIN=/usr/local/Python/pro/bin/python
+
+INSTALL_DIR=/usr/bin
+PYTHON_BIN=/usr/bin/python
+
+CC=gcc
+DEBUG=0
+CFLAGS=-DMTA_USER=\"$(MTA_USER)\" -DTRAC_USER=\"$(TRAC_USER)\" -DTRAC_SCRIPT_NAME=\"$(TRAC_SCRIPT_NAME)\" -DTRAC_SCRIPT_PATH=\"$(INSTALL_DIR)\" -DDEBUG=$(DEBUG)
+
+PYTHON_FILES=delete_spam.py email2trac.py
+WRAPPER_SRC=run_email2trac.c run_email2trac.h
+
+all: run_email2trac
+
+run_email2trac: $(WRAPPER_SRC)
+	$(CC) $(CFLAGS) -o $@ run_email2trac.c
+
+install: all
+	cp run_email2trac $(INSTALL_DIR)
+	chmod u+s $(INSTALL_DIR)/run_email2trac
+	chown root $(INSTALL_DIR)/run_email2trac
+	for script in $(PYTHON_FILES) ; \
+	do \
+	  sed -e "s%^\#\!/usr/bin/python%\#\!$(PYTHON_BIN)%" $$script > $(INSTALL_DIR)/$$script ; \
+	  chmod a+x $(INSTALL_DIR)/$$script ; \
+	done
+
+clean:
+	rm run_email2trac
Index: /emailtotracscript/trunk/README
===================================================================
--- /emailtotracscript/trunk/README	(revision 13)
+++ /emailtotracscript/trunk/README	(revision 13)
@@ -0,0 +1,22 @@
+email2trac - utilities
+----------------------
+
+This is a release of the SARA package email2trac that contains utilities that 
+we use to convert emails to trac tickets. The initial setup was made by 
+Daniel Lundin from Edgewall Software. SARA has extend the initial setup,  
+with the following extensions:
+
+  - HTML messages
+  - Attachments
+  - Use commandline options
+  - Use config file to change the behaviour of the email2trac.py program
+  - Some unicode support for special characters in the headers of an email
+    message
+
+See INSTALL for the how to setup the utilities
+
+Comments or Suggestions mail them to: 
+Bas van der Vlies <basv@sara.nl>
+Walter de Jong <walter@sara.nl>
+
+http://www.sara.nl for more info about SARA.
Index: /emailtotracscript/trunk/delete_spam.py
===================================================================
--- /emailtotracscript/trunk/delete_spam.py	(revision 13)
+++ /emailtotracscript/trunk/delete_spam.py	(revision 13)
@@ -0,0 +1,116 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2002
+#
+# This file is part of the pxeconfig utils
+#
+# This program is free software; you can redistribute it and/or modify it 
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+#
+"""
+Author: Bas van der Vlies
+Date  : 29 September 2205
+Desc. : Delete Spam tickets from database. Else we get an lot of 
+        tickets
+
+Usage :
+	delete_spam [ -f <configfile> ]
+
+defaults:
+	configfile = /etc/email2trac.conf
+
+SVN Info:
+        $Id: delete_spam.py 1512 2005-10-26 09:20:37Z jaap $
+"""
+from trac import Environment, Ticket
+
+import os
+import sys
+import getopt
+import shutil
+import ConfigParser
+
+def ReadConfig(file):
+	"""
+	Parse the config file
+	"""
+
+	if not os.path.isfile(file):
+		print 'File %s does not exists' %file
+		sys.exit(1)
+
+	config = ConfigParser.ConfigParser()
+
+	try:
+	  config.read(file)
+	except ConfigParser.MissingSectionHeaderError,detail:
+	  print detail
+	  sys.exit(1)
+
+	defaults = config.defaults()
+	if not defaults.has_key('project'):
+		print 'You have define the location of your trac project, eg:'
+		print '\t project: /var/trac/<projectname>'
+		sys.exit(1)
+	  
+	return defaults
+
+
+def delete_spam(project, debug):
+			env = Environment.Environment(project, create=0)
+			db = env.get_db_cnx()
+			
+			cursor = db.cursor()
+
+			# Delete the attachments associated with Spam tickets
+			#
+			cursor.execute("SELECT id FROM ticket WHERE  component = 'Spam';") 
+			while 1:
+				row = cursor.fetchone()
+				if not row:
+					break
+				spam_id =  row[0]
+				attachment_dir = os.path.join(env.get_attachments_dir(), 'ticket', str(spam_id)) 
+				if os.path.exists(attachment_dir):
+					if debug:
+						print 'delete %s : %s' %(spam_id, attachment_dir)
+					shutil.rmtree(attachment_dir)
+
+			cursor.execute("DELETE FROM ticket WHERE  component = 'Spam';") 
+			db.commit()
+
+if __name__ == '__main__':
+	# Default config file
+	#
+	configfile = '/etc/email2trac.conf'
+
+	try:
+		 opts, args = getopt.getopt(sys.argv[1:], 'hf:', ['help', 'file='])
+	except getopt.error,detail:
+		print __doc__
+		print detail
+		sys.exit(1)
+
+	for opt,value in opts:
+		if opt in [ '-h', '--help']:
+			print __doc__ 
+			sys.exit(0) 
+		elif opt in ['-f', '--file']:
+			configfile = value
+	
+	settings = ReadConfig(configfile)
+	delete_spam(settings['project'], int(settings['debug']))
+	print 'Spam is deleted succesfully..' 
+
+# EOB
Index: /emailtotracscript/trunk/email2trac.conf
===================================================================
--- /emailtotracscript/trunk/email2trac.conf	(revision 13)
+++ /emailtotracscript/trunk/email2trac.conf	(revision 13)
@@ -0,0 +1,11 @@
+[DEFAULT]
+project: /data/trac/test
+debug: 2
+umask: 022
+spam_level: 4
+reply_address: 1
+mailto_link: 1
+umask: 022
+email_comment: >
+email_header: 1
+trac_version: 0.9
Index: /emailtotracscript/trunk/email2trac.py
===================================================================
--- /emailtotracscript/trunk/email2trac.py	(revision 13)
+++ /emailtotracscript/trunk/email2trac.py	(revision 13)
@@ -0,0 +1,547 @@
+#!/usr/bin/python
+# Copyright (C) 2002
+#
+# This file is part of the email2trac utils
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+#
+"""
+emailfilter.py -- Email tickets to Trac.
+
+A simple MTA filter to create Trac tickets from inbound emails.
+
+Copyright 2005, Daniel Lundin <daniel@edgewall.com>
+Copyright 2005, Edgewall Software
+
+Changed By: Bas van der Vlies <basv@sara.nl>
+Date      : 13 September 2005
+Descr.    : Added config file and command line options, spam level
+            detection, reply address and mailto option. Unicode support
+
+Changed By: Walter de Jong <walter@sara.nl>
+Descr.    : multipart-message code and trac attachments
+
+
+The scripts reads emails from stdin and inserts directly into a Trac database.
+MIME headers are mapped as follows:
+
+	* From:      => Reporter
+	             => CC (Optional via reply_address option)
+	* Subject:   => Summary
+	* Body       => Description
+	* Component  => Can be set to SPAM via spam_level option
+
+How to use
+----------
+ * Create an config file:
+	[DEFAULT]                    # REQUIRED
+	project: /data/trac/test     # REQUIRED
+	debug: 1                     # OPTIONAL, if set print some DEBUG info
+	spam_level: 4                # OPTIONAL, if set check for SPAM mail 
+	reply_address: 1             # OPTIONAL, if set then fill in ticket CC field
+        umask: 022                   # OPTIONAL, if set then use this umask for creation of the attachments
+	mailto_link: 1               # OPTIONAL, if set then [mailto:<CC>] in description 
+	trac_version: 0.8            # OPTIONAL, default is 0.9
+        
+ * default config file is : /etc/email2trac.conf
+
+ * Commandline opions:
+                -h | --help
+                -c <value> | --component=<value>
+                -f <config file> | --file=<config file>
+                -p <project name> | --project=<project name>
+
+SVN Info:
+        $Id: email2trac.py 1523 2005-11-01 09:27:51Z bas $
+"""
+
+import os
+import sys
+import string
+import getopt
+import stat
+import time
+import email
+import re
+import urllib
+import unicodedata
+import ConfigParser
+from email import Header
+from stat import *
+import mimetypes
+
+trac_default_version = 0.9
+
+class TicketEmailParser(object):
+	env = None
+	comment = '> '
+    
+	def __init__(self, env, parameters, version):
+		self.env = env
+
+		# Database connection
+		#
+		self.db = None
+
+		self.VERSION = version
+		if self.VERSION > 0.8:
+			self.new_ticket = ticket.Ticket
+			self.get_config = self.env.config.get
+		else:
+			self.new_ticket = Ticket.Ticket
+			self.get_config = self.env.get_config
+
+		if parameters.has_key('umask'):
+			os.umask(int(parameters['umask'], 8))
+
+		if parameters.has_key('debug'):
+			self.DEBUG = int(parameters['debug'])
+		else:
+			self.DEBUG = 0
+
+		if parameters.has_key('reply_address'):
+			self.CC = int(parameters['reply_address'])
+		else:
+			self.CC = 0
+
+		if parameters.has_key('mailto_link'):
+			self.MAILTO = int(parameters['mailto_link'])
+		else:
+			self.MAILTO = 0
+
+		if parameters.has_key('spam_level'):
+			self.SPAM_LEVEL = int(parameters['spam_level'])
+		else:
+			self.SPAM_LEVEL = 0
+
+		if parameters.has_key('email_comment'):
+			self.comment = str(parameters['email_comment'])
+
+		if parameters.has_key('email_header'):
+			self.EMAIL_HEADER = int(parameters['email_header'])
+		else:
+			self.EMAIL_HEADER = 0
+
+
+	# X-Spam-Score: *** (3.255) BAYES_50,DNS_FROM_AHBL_RHSBL,HTML_
+	# Note if Spam_level then '*' are included
+	def spam(self, message):
+		if message.has_key('X-Spam-Score'):
+			spam_l = string.split(message['X-Spam-Score'])
+			number = spam_l[0].count('*')
+
+			if number >= self.SPAM_LEVEL:
+				return number
+
+		return 0
+
+	def to_unicode(self, str):
+		"""
+		Email has 7 bit ASCII code, convert it to unicode with the charset
+		that is encoded in 7-bit ASCII code and encode it as utf-8 so TRAC 
+		understands it.
+		"""
+		results =  Header.decode_header(str)
+		str = None
+		for text,format in results:
+			if format:
+				try:
+					temp = unicode(text, format)
+				except UnicodeError:
+					# This always works 
+					#
+					temp = unicode(text, 'iso-8859-15')
+				temp =  temp.encode('utf-8')
+			else:
+				temp = string.strip(text)
+
+			if str:
+				str = '%s %s' %(str, temp)
+			else:
+				str = temp
+
+		return str
+
+	def debug_attachments(self, message):
+		n = 0
+		for part in message.walk():
+			if part.get_content_maintype() == 'multipart':      # multipart/* is just a container
+				print 'TD: multipart container'
+				continue
+
+			n = n + 1
+			print 'TD: part%d: Content-Type: %s' % (n, part.get_content_type())
+			print 'TD: part%d: filename: %s' % (n, part.get_filename())
+
+			if part.is_multipart():
+				print 'TD: this part is multipart'
+				payload = part.get_payload(decode=1)
+				print 'TD: payload:', payload
+			else:
+				print 'TD: this part is not multipart'
+
+			part_file = '/var/tmp/part%d' % n
+			print 'TD: writing part%d (%s)' % (n,part_file)
+			fx = open(part_file, 'wb')
+			text = part.get_payload(decode=1)
+			if not text:
+				text = '(None)'
+			fx.write(text)
+			fx.close()
+			try:
+				os.chmod(part_file,S_IRWXU|S_IRWXG|S_IRWXO)
+			except OSError:
+				pass
+
+	def email_header_txt(self, m):
+#		if not m['Subject']:
+#			subject = '(geen subject)'
+#		else:
+#			subject = self.to_unicode(m['Subject'])
+#
+#		head = "'''Subject:''' %s [[BR]]" % subject
+#		if m['From'] and len(m['From']) > 0:
+#			head = "%s'''From:''' %s [[BR]]" % (head, m['From'])
+#		if m['Date'] and len(m['Date']) > 0:
+#			head = "%s'''Date:''' %s [[BR]]" %(head, m['Date'])
+
+		str = ''
+		if m['To'] and len(m['To']) > 0 and m['To'] != 'hic@sara.nl':
+			str = "'''To:''' %s [[BR]]" %(m['To'])
+		if m['Cc'] and len(m['Cc']) > 0:
+			str = "%s'''Cc:''' %s [[BR]]" % (str, m['Cc'])
+
+		return str
+
+	def parse(self, fp):
+		msg = email.message_from_file(fp)
+		if not msg:
+			return
+
+		if self.DEBUG > 1:	  # save the entire e-mail message text
+			msg_file = '/var/tmp/msg.txt' 
+			print 'TD: saving email to %s' % msg_file
+			fx = open(msg_file, 'wb')
+			fx.write('%s' % msg)
+			fx.close()
+			try:
+				os.chmod(msg_file,S_IRWXU|S_IRWXG|S_IRWXO)
+			except OSError:
+				pass
+
+		self.db = self.env.get_db_cnx()
+		tkt = self.new_ticket(self.env)
+		tkt['status'] = 'new'
+
+		# Some defaults
+		#
+		tkt['milestone'] = self.get_config('ticket', 'default_milestone')
+		tkt['priority'] = self.get_config('ticket', 'default_priority')
+		tkt['severity'] = self.get_config('ticket', 'default_severity')
+		tkt['version'] = self.get_config('ticket', 'default_version')
+
+		if not msg['Subject']:
+			tkt['summary'] = '(geen subject)'
+		else:
+			tkt['summary'] = self.to_unicode(msg['Subject'])
+
+		if self.SPAM_LEVEL and self.spam(msg):
+			print 'This message is a SPAM. Automatic ticket insertion refused (SPAM level > %d' % self.SPAM_LEVEL
+			sys.exit(1)
+
+		if settings.has_key('component'):
+			tkt['component'] = settings['component']
+		else:
+			tkt['component'] = self.get_config('ticket', 'default_component')
+
+		# Get default owner for component
+		#
+		cursor = self.db.cursor()
+		sql = 'SELECT owner FROM component WHERE name=\'%s\'' % tkt['component']
+		cursor.execute(sql)
+		tkt['owner'] = cursor.fetchone()[0]
+
+		from_str = self.to_unicode(msg['from'])
+		tkt['reporter'] = from_str
+		if self.CC:
+			tkt['cc'] = from_str
+
+# produce e-mail like header
+		head = ''
+		if self.EMAIL_HEADER > 0:
+			head = self.email_header_txt(msg)
+
+		if self.DEBUG > 0:
+			self.debug_attachments(msg)
+
+#
+#	put the message text in the ticket description
+#	message text can be plain text or html or something else
+#
+		has_description = 0
+		for part in msg.walk():
+			if part.get_content_maintype() == 'multipart':			# 'multipart/*' is a container for multipart messages
+				continue
+
+			if part.get_content_type() == 'text/plain':
+				body_text = part.get_payload(decode=1)			# try to decode
+				if not body_text:					# decode failed
+					body_text = part.get_payload(decode=0)		# do not decode
+
+				tkt['description'] = '\n{{{\n\n%s\n}}}\n' % body_text
+
+			elif part.get_content_type() == 'text/html':
+				tkt['description'] = '%s\n\n(see attachment for HTML mail message)\n' % head
+				body_text = tkt['description']
+
+			else:
+				tkt['description'] = '%s\n\n(see attachment for message)\n' % head
+				body_text = tkt['description']
+
+			has_description = 1
+			break		# we have the description, so break
+
+		if not has_description:
+			tkt['description'] = '%s\n\n(no plain text message, see attachments)' % head
+			has_description = 1
+
+		author, email_addr  = email.Utils.parseaddr(msg['from'])
+		if self.MAILTO:
+			mailto = self.html_mailto_link(author, email_addr, self.to_unicode(msg['subject']), body_text)
+			tkt['description'] = '%s\n%s %s' %(head, mailto, tkt['description'])
+
+		if self.VERSION > 0.8:
+			tkt['id'] = tkt.insert()
+		else:
+			tkt['id'] = tkt.insert(self.db)
+
+		#
+		# Just how to show to update description
+		#
+		#tkt['description'] = '\n{{{\n\n Bas is op nieuw bezig\n\n }}}\n' 
+		#tkt.save_changes(self.db, author, "Lekker bezig")
+		#
+		self.attachments(msg, tkt, author)
+
+
+	def mail_line(self, str):
+		return '%s %s' % (self.comment, str)
+
+
+	def html_mailto_link(self, author, mail_addr, subject, body):
+		if not author:
+			author = mail_addr
+		else:	
+			author = self.to_unicode(author)
+
+		# Must find a fix
+		#
+		#arr = string.split(body, '\n')
+		#arr = map(self.mail_line, arr)
+
+		#body = string.join(arr, '\n')
+		#body = '%s wrote:\n%s' %(author, body)
+
+		# Obsolete for reference
+		#
+		#body = self.to_unicode(body)
+		#body = urllib.quote(body)
+		#body = Header.encode(body)
+		#
+
+		# Temporary fix
+		body = '> Type your reply'
+		str = 'mailto:%s?subject=%s&body=%s' % (urllib.quote(mail_addr), urllib.quote('Re: %s' % subject), urllib.quote(body))
+		str = '\n{{{\n#!html\n<a href="%s">Reply to: %s</a>\n}}}\n' %(str, author)
+
+		return str
+
+	def attachments(self, message, ticket, user):
+		'''save any attachments as file in the ticket's directory'''
+
+		count = 0
+		first = 0
+		for part in message.walk():
+			if part.get_content_maintype() == 'multipart':		# multipart/* is just a container
+				continue
+
+			if not first:										# first content is the message
+				first = 1
+				if part.get_content_type() == 'text/plain':		# if first is text, is was already put in the description
+					continue
+
+			filename = part.get_filename() 
+			if not filename:
+				count = count + 1
+				filename = 'part%04d' % count
+
+				ext = mimetypes.guess_extension(part.get_type())
+				if not ext:
+					ext = '.bin'
+
+				filename = '%s%s' % (filename, ext)
+			else:
+				filename = self.to_unicode(filename)
+
+			if '/' in filename:
+				filename = os.path.basename(filename)
+
+			url_filename = urllib.quote(filename)
+
+			if self.VERSION > 0.8:
+				tmpfile = '/tmp/email2trac-ticket%sattachment' % str(ticket['id'])
+			else:
+				dir = os.path.join(self.env.get_attachments_dir(), 'ticket', 
+				                    	urllib.quote(str(ticket['id'])))
+				if not os.path.exists(dir):
+					mkdir_p(dir, 0755)
+
+				tmpfile = os.path.join(dir, url_filename)
+
+			f = open(tmpfile, 'wb')
+			text = part.get_payload(decode=1)
+			if not text:
+				text = '(None)'
+			f.write(text)
+
+			# get the filesize
+			#
+			stats = os.lstat(tmpfile) 
+			filesize = stats[stat.ST_SIZE]
+
+			# Insert the attachment it differs for the different TRAC versions
+			#
+			if self.VERSION > 0.8:
+				att = attachment.Attachment(self.env,'ticket',ticket['id'])
+				att.insert(url_filename,f,filesize)
+				f.close()
+			else:
+				cursor = self.db.cursor()
+				cursor.execute('INSERT INTO attachment VALUES("%s","%s","%s",%d,%d,"%s","%s","%s")' 
+					%('ticket', urllib.quote(str(ticket['id'])), filename + '?format=raw', filesize, 
+					  int(time.time()),'', user, 'e-mail') ) 
+				self.db.commit()
+
+
+def mkdir_p(dir, mode):
+	'''do a mkdir -p'''
+
+	arr = string.split(dir, '/')
+	path = ''
+	for part in arr:
+		path = '%s/%s' % (path, part)
+		try:
+			stats = os.stat(path)
+		except OSError:
+			os.mkdir(path, mode)
+
+
+def ReadConfig(file):
+	"""
+	Parse the config file
+	"""
+
+	if not os.path.isfile(file):
+		print 'File %s does not exists' %file
+		sys.exit(1)
+
+	config = ConfigParser.ConfigParser()
+
+	try:
+	  config.read(file)
+	except ConfigParser.MissingSectionHeaderError,detail:
+	  print detail
+	  sys.exit(1)
+
+	defaults = config.defaults()
+	if not defaults.has_key('project') and  not defaults.has_key('project_root'):
+		print 'You have to define the location of your trac project'
+		print 'or the root of your projects, eg:'
+		print '\t project: /var/trac/<projectname>'
+		print '\t project_root: /var/trac'
+		sys.exit(1)
+	  
+	return defaults
+
+
+if __name__ == '__main__':
+	# Default config file
+	#
+	configfile = '/etc/email2trac.conf'
+	project = ''
+	component = ''
+	
+	try:
+		opts, args = getopt.getopt(sys.argv[1:], 'chf:p:', ['component=','help', 'file=', 'project='])
+	except getopt.error,detail:
+		print __doc__
+		print detail
+		sys.exit(1)
+
+	for opt,value in opts:
+		if opt in [ '-h', '--help']:
+			print __doc__
+			sys.exit(0)
+		elif opt in ['-c', '--component']:
+			component = value
+		elif opt in ['-f', '--file']:
+			configfile = value
+		elif opt in ['-p', '--project']:
+			project = value
+
+	settings = ReadConfig(configfile)
+
+	if not settings.has_key('project') and not project:
+		print 'You must specify a project either in configuration file'
+		print 'or with option --project'
+		sys.exit(1)
+		
+	if project:
+		if settings.has_key('project_root') :
+			settings['project'] = os.path.join(settings['project_root'], project)
+		else:
+			print 'You must specify a project root in configuration file'
+			print 'in order to use option --project'
+			sys.exit(1)
+	else:
+		if not re.search("/",settings['project']):
+			if settings.has_key('project_root') :
+				settings['project'] = os.path.join(settings['project_root'], settings['project'])
+			else:
+				print 'You must specify a project root in configuration file'
+				print 'or specify the project full path'
+				sys.exit(1)
+
+	if component:
+		settings['component'] = component
+
+	if settings.has_key('trac_version'):
+		version = float(settings['trac_version'])
+	else:
+		version = trac_default_version
+
+	if version > 0.8:
+		from trac import attachment, config, env, ticket
+		env = env.Environment(settings['project'], create=0)
+		ticket_mod = ticket
+	else:
+		from trac import Environment, Ticket
+		env = Environment.Environment(settings['project'], create=0)
+		ticket_mod = Ticket
+		
+	tktparser = TicketEmailParser(env, settings, version)
+	tktparser.parse(sys.stdin)
+
+# EOB
Index: /emailtotracscript/trunk/email2trac_test.sh
===================================================================
--- /emailtotracscript/trunk/email2trac_test.sh	(revision 13)
+++ /emailtotracscript/trunk/email2trac_test.sh	(revision 13)
@@ -0,0 +1,1 @@
+/usr/bin/python /var/tmp/email2trac-0.3.0/email2trac.py -f /var/tmp/email2trac-0.3.0/email2trac.conf >/var/tmp/out 2>&1
Index: /emailtotracscript/trunk/run_email2trac.c
===================================================================
--- /emailtotracscript/trunk/run_email2trac.c	(revision 13)
+++ /emailtotracscript/trunk/run_email2trac.c	(revision 13)
@@ -0,0 +1,102 @@
+/*
+	run_email2trac.c
+	Authors: Bas van der Vlies and Walter de Jong
+
+	Only nobody can become the user www-data. Postfix uses this
+	user to start an program
+
+# Copyright (C) 2002
+#
+# This file is part of the email2trac utils
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+#
+*/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/stat.h>
+#include <string.h>
+#include "run_email2trac.h"
+
+#ifndef DEBUG
+#define DEBUG 0
+#endif
+
+int main(int argc, char** argv) {
+
+  int i,j;
+  int caller = getuid();
+  int status;
+  char trac_script[255];
+  char** trac_script_args;
+  struct passwd *TRAC; 
+  struct passwd *MTA;
+  struct stat script_attrs;
+  
+  strcat(trac_script,TRAC_SCRIPT_PATH);
+  strcat(trac_script,"/");
+  strcat(trac_script,TRAC_SCRIPT_NAME);
+
+  /* First copy arguments passed to the wrapper as scripts arguments
+     after filtering out some of the possible script options */
+  trac_script_args = (char**) malloc((argc+1)*sizeof(char*));
+  trac_script_args[0] = TRAC_SCRIPT_NAME;
+  for (i=j=1; i<argc; i++) {
+    if ( (strcmp(argv[i],"--file") == 0) || 
+	 (strcmp(argv[i],"-f") == 0) ) {
+      i++;
+      continue;
+    }
+    
+    trac_script_args[j] = argv[i];
+    j++;
+  }
+  trac_script_args[j] = NULL;
+
+  
+  /* Check caller */
+  
+  MTA = getpwnam(MTA_USER);
+  if ( caller !=  MTA->pw_uid ) {
+    if ( DEBUG ) printf("Invalid caller UID (%d)\n",caller);
+    return -2;     /* 254 : Invalid caller */
+  }
+  
+  
+  /* set UID/GID to Trac (or apache) user */
+  if ( TRAC = getpwnam(TRAC_USER) ) {
+    setuid(TRAC->pw_uid);
+    setgid(TRAC->pw_gid);
+  } else {
+    if ( DEBUG ) printf("Invalid Trac user (%s)\n",TRAC_USER);
+    return -3;     /* 253 : Trac user not found */
+  }
+	 
+  /* Check that script exists */
+  if ( stat(trac_script,&script_attrs) ) {
+    if ( DEBUG ) printf("Script not found (%s)\n",trac_script);
+    return -4;    /* 252 : script not found */
+  }
+ 
+  /* Execute script */
+  status = execv(trac_script, trac_script_args);
+  if ( DEBUG ) printf("Script %s execution failure (error=%d). Check permission and interpreter path.\n",trac_script,status);
+  return -1;     /* 255 : should never reach this point */
+
+}
+
+/* EOB */
Index: /emailtotracscript/trunk/run_email2trac.h
===================================================================
--- /emailtotracscript/trunk/run_email2trac.h	(revision 13)
+++ /emailtotracscript/trunk/run_email2trac.h	(revision 13)
@@ -0,0 +1,24 @@
+/*
+Local site configuration
+Value defined here are just default values than can be overriden at compile time
+See Makefile.
+*/
+
+/* User the MTA is running under */
+#ifndef MTA_USER
+#define MTA_USER "nobody"
+#endif
+
+/* A user with write access to Trac DB */
+#ifndef TRAC_USER
+#define TRAC_USER "www-data"
+#endif
+
+/* email2trac script name and path */
+#ifndef TRAC_SCRIPT_NAME
+#define TRAC_SCRIPT_NAME "email2trac.py"
+#endif
+#ifndef TRAC_SCRIPT_PATH
+#define TRAC_SCRIPT_PATH "/usr/bin"
+#endif
+
Index: /emailtotracscript/trunk/test7.eml
===================================================================
--- /emailtotracscript/trunk/test7.eml	(revision 13)
+++ /emailtotracscript/trunk/test7.eml	(revision 13)
@@ -0,0 +1,109 @@
+Received: from surfboard.ka.sara.nl ([145.100.6.3]) by douwes.ka.sara.nl with Microsoft SMTPSVC(6.0.3790.1830);
+	 Fri, 23 Sep 2005 13:52:07 +0200
+Received: from orwell.sara.nl ([145.100.16.26]) by surfboard.ka.sara.nl with Microsoft SMTPSVC(6.0.3790.1830);
+	 Fri, 23 Sep 2005 13:52:07 +0200
+Received: from mta.sara.nl (mta.sara.nl [145.100.16.144])
+	by orwell.sara.nl (8.12.10+Sun/8.12.10) with ESMTP id j8NBq5aM011272
+	for <walter@sara.nl>; Fri, 23 Sep 2005 13:52:05 +0200 (MEST)
+Received: from [145.100.6.95] (walter.ka.sara.nl [145.100.6.95])
+	by mta.sara.nl (8.12.10+Sun/8.12.10) with ESMTP id j8NBq52B000945
+	for <walter@sara.nl>; Fri, 23 Sep 2005 13:52:05 +0200 (MEST)
+Message-ID: <4333EC65.2020909@sara.nl>
+Date: Fri, 23 Sep 2005 13:52:05 +0200
+From: Walter de Jong <walter@sara.nl>
+Organization: SARA
+User-Agent: Mozilla Thunderbird 1.0.6 (Windows/20050716)
+X-Accept-Language: en-us, en
+MIME-Version: 1.0
+To: "Walter de Jong" <walter@sara.nl>
+Subject: test #7
+Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="------------ms030807040502080509050606"
+X-Spam-Score:  (-5.899) ALL_TRUSTED,BAYES_00,autolearn=ham
+X-Scanned-By: MIMEDefang 2.51 on 145.100.16.26
+Return-Path: walter@sara.nl
+X-OriginalArrivalTime: 23 Sep 2005 11:52:07.0723 (UTC) FILETIME=[394F5FB0:01C5C035]
+
+This is a cryptographically signed message in MIME format.
+
+--------------ms030807040502080509050606
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 7bit
+
+test #7, zonder attachment
+
+-- 
+                   *** If you build it, they will come ***
+
+HPC Systems Programmer at SARA Computing and Network Services
+People should be able to e-mail me, spambots should not.
+
+Digital signature can be verified by trusting the CA certificate
+at http://ca.dutchgrid.nl/medium/cacert.pem
+
+--------------ms030807040502080509050606
+Content-Type: application/x-pkcs7-signature; name="smime.p7s"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename="smime.p7s"
+Content-Description: S/MIME Cryptographic Signature
+
+MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIJvDCC
+BNowggPCoAMCAQICAgK0MA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAk5MMQ8wDQYDVQQK
+EwZOSUtIRUYxMjAwBgNVBAMTKU5JS0hFRiBtZWRpdW0tc2VjdXJpdHkgY2VydGlmaWNhdGlv
+biBhdXRoMB4XDTA1MDUxOTAwMDAwMFoXDTA2MDUxOTE0NDMxNlowTDESMBAGA1UEChMJZHV0
+Y2hncmlkMQ4wDAYDVQQKEwV1c2VyczENMAsGA1UEChMEc2FyYTEXMBUGA1UEAxMOV2FsdGVy
+IERlIEpvbmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMlIIQ8Lm0+a5R/FH/BisLlz
+cYGmtEsiMQsQYe/CDFFLUgFXiAAFzeK44GKOu/G0pWorMlYl2cygEvjYkUsCUjKf0ux30Fkd
+M7Iw9bivKCCJkI28VVFzuVMFal2jC1NqsUNpmygCuUHrRG0pSN3kC3Q87SJR7NHN32RCu9SV
+lctDAgMBAAGjggJCMIICPjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIE8DA4BgNVHR8E
+MTAvMC2gK6AphidodHRwOi8vY2EuZHV0Y2hncmlkLm5sL21lZGl1bS9jYWNybC5wZW0wGgYD
+VR0gBBMwETAPBg0rBgEEAdFCBAICAQICMHoGA1UdIwRzMHGAFFsFOpnG1SK9/ZSA/BGo0PFx
+1kukoVakVDBSMQswCQYDVQQGEwJOTDEPMA0GA1UEChMGTklLSEVGMTIwMAYDVQQDEylOSUtI
+RUYgbWVkaXVtLXNlY3VyaXR5IGNlcnRpZmljYXRpb24gYXV0aIIBADAdBgNVHQ4EFgQURuiz
+iHUKl4eFt/KAIg/whPxKrYwwEQYJYIZIAYb4QgEBBAQDAgXgMDQGCWCGSAGG+EIBCAQnFiVo
+dHRwOi8vY2EuZHV0Y2hncmlkLm5sL21lZGl1bS9wb2xpY3kvMIHIBglghkgBhvhCAQ0EgboW
+gbdDZXJ0aWZpY2F0ZSBpc3N1ZWQgdW5kZXIgRHV0Y2hHcmlkIG1lZGl1bS1zZWN1cml0eSBw
+b2xpY3kgdmVyc2lvbiAyLjI7bGltaXRlZCBsaWFiaWxpdGllcyBhcHBseSwgc2VlIGh0dHA6
+Ly9jYS5kdXRjaGdyaWQubmwvbWVkaXVtL3BvbGljeS8gZm9yIGRldGFpbHM7Q2VydGlmaWNh
+dGUgVGFnOiAxYmRlZjIyZi1jOTQ4MjEwGQYDVR0RBBIwEIEOd2FsdGVyQHNhcmEubmwwDQYJ
+KoZIhvcNAQEFBQADggEBAB7RL8aWaLxP79/QGbchaS6BnUr8Dw2piFtXZVQOEZAgyPvr/gtm
+21mr9abLX9kUJxQqDmwVgVSF4H0hwDQ7me19WInFfwSCLSnV28ueldmm/9Ej7n9iAtY5CJ/y
+2GH+lpEN2nq7/db6D7WN47/bFGdbMAeQ2gCBP4Xg4pbxDz4PtAxz2r5ImLrXkvK7ixw3j5EH
+d9kI6pzzWm8R6OhFx6Zz6iE81qc47nsphIftn6g7lUnBkbP+CwKqEaN+yNiibgJ/LElLUwAx
+XFsJwGmtpQNUrIhrRRHecZYyKW0Xo1WXQRhNHc8KmelzuRU0zMVcBN0XLXA9Y4t32+57VpDK
+9RAwggTaMIIDwqADAgECAgICtDANBgkqhkiG9w0BAQUFADBSMQswCQYDVQQGEwJOTDEPMA0G
+A1UEChMGTklLSEVGMTIwMAYDVQQDEylOSUtIRUYgbWVkaXVtLXNlY3VyaXR5IGNlcnRpZmlj
+YXRpb24gYXV0aDAeFw0wNTA1MTkwMDAwMDBaFw0wNjA1MTkxNDQzMTZaMEwxEjAQBgNVBAoT
+CWR1dGNoZ3JpZDEOMAwGA1UEChMFdXNlcnMxDTALBgNVBAoTBHNhcmExFzAVBgNVBAMTDldh
+bHRlciBEZSBKb25nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJSCEPC5tPmuUfxR/w
+YrC5c3GBprRLIjELEGHvwgxRS1IBV4gABc3iuOBijrvxtKVqKzJWJdnMoBL42JFLAlIyn9Ls
+d9BZHTOyMPW4ryggiZCNvFVRc7lTBWpdowtTarFDaZsoArlB60RtKUjd5At0PO0iUezRzd9k
+QrvUlZXLQwIDAQABo4ICQjCCAj4wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBPAwOAYD
+VR0fBDEwLzAtoCugKYYnaHR0cDovL2NhLmR1dGNoZ3JpZC5ubC9tZWRpdW0vY2FjcmwucGVt
+MBoGA1UdIAQTMBEwDwYNKwYBBAHRQgQCAgECAjB6BgNVHSMEczBxgBRbBTqZxtUivf2UgPwR
+qNDxcdZLpKFWpFQwUjELMAkGA1UEBhMCTkwxDzANBgNVBAoTBk5JS0hFRjEyMDAGA1UEAxMp
+TklLSEVGIG1lZGl1bS1zZWN1cml0eSBjZXJ0aWZpY2F0aW9uIGF1dGiCAQAwHQYDVR0OBBYE
+FEbos4h1CpeHhbfygCIP8IT8Sq2MMBEGCWCGSAGG+EIBAQQEAwIF4DA0BglghkgBhvhCAQgE
+JxYlaHR0cDovL2NhLmR1dGNoZ3JpZC5ubC9tZWRpdW0vcG9saWN5LzCByAYJYIZIAYb4QgEN
+BIG6FoG3Q2VydGlmaWNhdGUgaXNzdWVkIHVuZGVyIER1dGNoR3JpZCBtZWRpdW0tc2VjdXJp
+dHkgcG9saWN5IHZlcnNpb24gMi4yO2xpbWl0ZWQgbGlhYmlsaXRpZXMgYXBwbHksIHNlZSBo
+dHRwOi8vY2EuZHV0Y2hncmlkLm5sL21lZGl1bS9wb2xpY3kvIGZvciBkZXRhaWxzO0NlcnRp
+ZmljYXRlIFRhZzogMWJkZWYyMmYtYzk0ODIxMBkGA1UdEQQSMBCBDndhbHRlckBzYXJhLm5s
+MA0GCSqGSIb3DQEBBQUAA4IBAQAe0S/Glmi8T+/f0Bm3IWkugZ1K/A8NqYhbV2VUDhGQIMj7
+6/4LZttZq/Wmy1/ZFCcUKg5sFYFUheB9IcA0O5ntfViJxX8Egi0p1dvLnpXZpv/RI+5/YgLW
+OQif8thh/paRDdp6u/3W+g+1jeO/2xRnWzAHkNoAgT+F4OKW8Q8+D7QMc9q+SJi615Lyu4sc
+N4+RB3fZCOqc81pvEejoRcemc+ohPNanOO57KYSH7Z+oO5VJwZGz/gsCqhGjfsjYom4CfyxJ
+S1MAMVxbCcBpraUDVKyIa0UR3nGWMiltF6NVl0EYTR3PCpnpc7kVNMzFXATdFy1wPWOLd9vu
+e1aQyvUQMYIChzCCAoMCAQEwWDBSMQswCQYDVQQGEwJOTDEPMA0GA1UEChMGTklLSEVGMTIw
+MAYDVQQDEylOSUtIRUYgbWVkaXVtLXNlY3VyaXR5IGNlcnRpZmljYXRpb24gYXV0aAICArQw
+CQYFKw4DAhoFAKCCAYUwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx
+DxcNMDUwOTIzMTE1MjA1WjAjBgkqhkiG9w0BCQQxFgQUigoK2CfFbRuzSpV1autcqqGXhLsw
+UgYJKoZIhvcNAQkPMUUwQzAKBggqhkiG9w0DBzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcN
+AwICAUAwBwYFKw4DAgcwDQYIKoZIhvcNAwICASgwZwYJKwYBBAGCNxAEMVowWDBSMQswCQYD
+VQQGEwJOTDEPMA0GA1UEChMGTklLSEVGMTIwMAYDVQQDEylOSUtIRUYgbWVkaXVtLXNlY3Vy
+aXR5IGNlcnRpZmljYXRpb24gYXV0aAICArQwaQYLKoZIhvcNAQkQAgsxWqBYMFIxCzAJBgNV
+BAYTAk5MMQ8wDQYDVQQKEwZOSUtIRUYxMjAwBgNVBAMTKU5JS0hFRiBtZWRpdW0tc2VjdXJp
+dHkgY2VydGlmaWNhdGlvbiBhdXRoAgICtDANBgkqhkiG9w0BAQEFAASBgMgrVMfJZfvgP8Sk
+debMpVy2N3P1CDhPU/o5iszJ2naOnAr5Q1ki+KzBssGLYlLuw1WTMMUFe3r9zVOv1wXXjAu5
+7vcJm0zSS2t49UbsxTCwcfEcXeDMId3aSWAfbE46HyYhU4+WPZnDvGF8RioKCxJcN9RiotkG
+TqV+G89C0Q3EAAAAAAAA
+--------------ms030807040502080509050606--
