diff options
author | mkanat%bugzilla.org <> | 2006-10-17 16:08:06 +0200 |
---|---|---|
committer | mkanat%bugzilla.org <> | 2006-10-17 16:08:06 +0200 |
commit | c26d71326510b17b3da75c733254ec07178da884 (patch) | |
tree | b35b3c4da1f86af73c6987619811d7ec06eb228f /contrib | |
parent | 41e90677df45dc12590343ea88be4d8f6cb5eb87 (diff) | |
download | bugzilla-c26d71326510b17b3da75c733254ec07178da884.tar.gz bugzilla-c26d71326510b17b3da75c733254ec07178da884.tar.xz |
Bug 356924: Remove the old bug_email inbound email interface
Patch By Max Kanat-Alexander <mkanat@bugzilla.org> a=justdave
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/BugzillaEmail.pm | 78 | ||||
-rw-r--r-- | contrib/README.Mailif | 80 | ||||
-rwxr-xr-x | contrib/bug_email.pl | 1203 | ||||
-rw-r--r-- | contrib/bugmail_help.html | 223 | ||||
-rw-r--r-- | contrib/bugzilla.procmailrc | 30 | ||||
-rwxr-xr-x | contrib/bugzilla_email_append.pl | 197 |
6 files changed, 0 insertions, 1811 deletions
diff --git a/contrib/BugzillaEmail.pm b/contrib/BugzillaEmail.pm deleted file mode 100644 index c6b569c9d..000000000 --- a/contrib/BugzillaEmail.pm +++ /dev/null @@ -1,78 +0,0 @@ -# -*- Mode: perl; indent-tabs-mode: nil -*- - -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# This code is based on code found in bug_email.pl from the bugzilla -# email tracker. Initial contributors are :: -# Terry Weissman <terry@mozilla.org> -# Gregor Fischer <fischer@suse.de> -# Klaas Freitag <freitag@suse.de> -# Seth Landsman <seth@dworkin.net> -# Lance Larsh <lance.larsh@oracle.com> - -# The purpose of this module is to abstract out a bunch of the code -# that is central to email interfaces to bugzilla and its database - -# Contributor : Seth Landsman <seth@dworkin.net> - -# Initial checkin : 03/15/00 (SML) -# findUser() function moved from bug_email.pl to here - -push @INC, "../."; # this script now lives in contrib - -use strict; - -use Bugzilla; - -my $EMAIL_TRANSFORM_NONE = "email_transform_none"; -my $EMAIL_TRANSFORM_BASE_DOMAIN = "email_transform_base_domain"; -my $EMAIL_TRANSFORM_NAME_ONLY = "email_transform_name_only"; - -# change to do incoming email address fuzzy matching -my $email_transform = $EMAIL_TRANSFORM_NAME_ONLY; - -# This function takes an email address and returns the user email. -# matching is sloppy based on the $email_transform parameter -sub findUser($) { - my $dbh = Bugzilla->dbh; - my ($address) = @_; - # if $email_transform is $EMAIL_TRANSFORM_NONE, return the address, otherwise, return undef - if ($email_transform eq $EMAIL_TRANSFORM_NONE) { - my $stmt = q{SELECT login_name FROM profiles WHERE } . - $dbh->sql_istrcmp('login_name', '?'); - my $found_address = $dbh->selectrow_array($stmt, undef, $address); - return $found_address; - } elsif ($email_transform eq $EMAIL_TRANSFORM_BASE_DOMAIN) { - my ($username) = ($address =~ /(.+)@/); - my $stmt = q{SELECT login_name FROM profiles WHERE } . $dbh->sql_regexp( - $dbh->sql_istring('login_name'), $dbh->sql_istring('?')); - - my $found_address = $dbh->selectcol_arrayref($stmt, undef, $username); - my $domain; - my $new_address = undef; - foreach my $addr (@$found_address) { - ($domain) = ($addr =~ /.+@(.+)/); - if ($address =~ /$domain/) { - $new_address = $addr; - last; - } - } - return $new_address; - } elsif ($email_transform eq $EMAIL_TRANSFORM_NAME_ONLY) { - my ($username) = ($address =~ /(.+)@/); - my $stmt = q{SELECT login_name FROM profiles WHERE } . $dbh->sql_regexp( - $dbh->sql_istring('login_name'), $dbh->sql_istring('?')); - my $found_address = $dbh->selectrow_array($stmt, undef, $username); - return $found_address; - } -} - -1; diff --git a/contrib/README.Mailif b/contrib/README.Mailif deleted file mode 100644 index 0c65cef83..000000000 --- a/contrib/README.Mailif +++ /dev/null @@ -1,80 +0,0 @@ - -The Bugzilla Mail interface -=========================== - -(UPDATE 03/14/00 to better reflect reality by SML) - -The Bugzilla Mail interface allows to submit bugs to Bugzilla by email. - -The Mail Interface Contribution consists of three files: -README.Mailif - this readme. -bug_email.pl - the script -bugmail_help.html - a user help html site - -Installation: - -Next is to add a user who receives the bugmails, e. g. bugmail. Create a -mail account and a home directory for the user. - -The mailinterface script bug_email.pl needs to get the mail through stdin. -I use procmail for that, with the following line in the .procmailrc: - -BUGZILLA_HOME=/usr/local/httpd/htdocs/bugzilla -:0 c -|(cd $BUGZILLA_HOME/contrib; ./bug_email.pl) - -This defines the Bugzilla directory as the variable BUGZILLA_HOME and passes -all incoming mail to the script after cd'ing into the bugzilla home. - -In some cases, it is necessary to alter the headers of incoming email. The -additional line to procmail : - -:0 fhw -| formail -I "From " -a "From " - -fixes many problems. - -See bugzilla.procmailrc for a sample procmailrc that works for me (SML) and -also deals with bugzilla_email_append.pl - -Customation: - -There are some values inside the script which need to be customized for your -needs: - -1. In sub-routine Reply (search 'sub Reply': -there is the line - print MAIL "From: Bugzilla Mailinterface<yourmail\@here.com>\n"; - ^^^^^^^^^^^^^^^^^^^^ -Fill in your correct mail here. That will make it easy for people to reply -to the mail. - -2. check, if your sendmail resides in /usr/sbin/sendmail, change the path if neccessary. -Search the script after 'default' - you find some default-Settings for bug -reports, which are used, if the sender did not send a field for it. The defaults -should be checked and changed. - -That's hopefully all, we will come up with any configuration file or something. - - -If your mail works, your script will insert mails from now on. - -The mailinterface supports two commandline switches: - -There are two command line switches : - --t: Testmode - The mailinterface does not really insert the bug into the database, but - writes some debug output to stdout and writes the mail into the file - bug_email_test.log in the data-dir. - --r: restricted mode - All lines before the first line with a keyword character are skipped. - In not restricted, default mode, these lines are added to the long - description of the bug. - - -02/2000 - Klaas Freitag, SuSE GmbH <freitag@suse.de> -03/2000 - Seth M. Landsman <seth@cs.brandeis.edu> - bug_email.pl now lives out of bugzilla/contrib - added line about formail diff --git a/contrib/bug_email.pl b/contrib/bug_email.pl deleted file mode 100755 index 0f898da52..000000000 --- a/contrib/bug_email.pl +++ /dev/null @@ -1,1203 +0,0 @@ -#!/usr/bin/perl -w -# -*- Mode: perl; indent-tabs-mode: nil -*- -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Bugzilla Bug Tracking System. -# -# The Initial Developer of the Original Code is Netscape Communications -# Corporation. Portions created by Netscape are -# Copyright (C) 1998 Netscape Communications Corporation. All -# Rights Reserved. -# Contributor(s): Terry Weissman <terry@mozilla.org> -# Gregor Fischer <fischer@suse.de> -# Klaas Freitag <freitag@suse.de> -# Seth Landsman <seth@dworkin.net> -# Ludovic Dubost <ludovic@pobox.com> -############################################################### -# Bugzilla: Create a new bug via email -############################################################### -# The email needs to be feeded to this program on STDIN. -# This is usually done by having an entry like this in your -# .procmailrc: -# -# BUGZILLA_HOME=/usr/local/httpd/htdocs/bugzilla -# :0 c -# |(cd $BUGZILLA_HOME/contrib; ./bug_email.pl) -# -# -# Installation note: -# -# You need to work with bug_email.pl the MIME::Parser installed. -# -# $Id: bug_email.pl,v 1.45 2006/09/22 23:14:53 lpsolit%gmail.com Exp $ -############################################################### - -# 02/12/2000 (SML) -# - updates to work with most recent database changes to the bugs database -# - updated so that it works out of bugzilla/contrib -# - initial checkin into the mozilla CVS tree (yay) - -# 02/13/2000 (SML) -# - email transformation code. -# EMAIL_TRANSFORM_NONE does exact email matches -# EMAIL_TRANSFORM_NAME_ONLY matches on the username -# EMAIL_TRANSFORM_BASE_DOMAIN matches on the username and checks the domain of -# to see that the one in the database is a subset of the one in the sender address -# this is probably prone to false positives and probably needs more work. - -# 03/07/2000 (SML) -# - added in $DEFAULT_PRODUCT and $DEFAULT_COMPONENT. i.e., if $DEFAULT_PRODUCT = "PENDING", -# any email submitted bug will be entered with a product of PENDING, if no other product is -# specified in the email. - -# 10/21/2003 (Ludovic) -# - added $DEFAULT_VERSION, similar to product and component above -# - added command line switches to override version, product, and component, so separate -# email addresses can be used for different product/component/version combinations. -# Example for procmail: -# # Feed mail to stdin of bug_email.pl -# :0 Ec -# * !^Subject: .*[Bug .*] -# RESULT=|(cd $BUGZILLA_HOME/contrib && ./bug_email.pl -p='Tier_3_Operations' -c='General' ) - -# Next round of revisions : -# - querying a bug over email -# - appending a bug over email -# - keywords over email -# - use the Bugzilla parameters functionality to edit and save this script's parameters -# - integrate some setup in the checksetup.pl script -# - gpg signatures for security - -use strict; -use MIME::Parser; - -BEGIN { - chdir '..'; # this script lives in contrib - push @INC, "contrib/."; - push @INC, "."; -} - -use lib "."; -use lib "../"; - -use Bugzilla; -use BugzillaEmail; -use Bugzilla::Constants; -use Bugzilla::Util; -use Bugzilla::BugMail; -use Bugzilla::User; -use Bugzilla::Product; -use Bugzilla::Component; - -my @mailerrors = (); # Buffer for Errors in the mail -my @mailwarnings = (); # Buffer for Warnings found in the mail -my $critical_err = 0; # Counter for critical errors - must be zero for success -my %Control; -my $Header = ""; -my @RequiredLabels = (); -my @AllowedLabels = (); -my $Body = ""; -my @attachments = (); - -my $product_valid = 0; -my $test = 0; -my $restricted = 0; -my $SenderShort; -my $Message_ID; - -my $dbh = Bugzilla->dbh; - -# change to use default product / component functionality -my $DEFAULT_PRODUCT = "PENDING"; -my $DEFAULT_COMPONENT = "PENDING"; -my $DEFAULT_VERSION = "unspecified"; - -############################################################### -# storeAttachments -# -# in this sub, attachments found in the dump-sub will be written to -# the database. The info, which attachments need saving is stored -# in the global @attachments-list. -# The sub returns the number of stored attachments. -sub storeAttachments( $$ ) -{ - my ($bugid, $submitter_id ) = @_; - my $maxsize = 0; - my $data; - my $listref = \@attachments; - my $att_count = 0; - my $dbh = Bugzilla->dbh; - - $submitter_id ||= 0; - - my $timestamp = $dbh->selectrow_array("SELECT NOW()"); - my $sth_attach = $dbh->prepare(q{ - INSERT INTO attachments (bug_id, creation_ts, description, - mimetype, ispatch, filename, submitter_id) - VALUES (?, ?, ?, ?, 0, ?, ?) }); - - my $sth_data = $dbh->prepare(q{INSERT INTO attach_data (id, thedata) - VALUES (LAST_INSERT_ID(), ?)}); - foreach my $pairref ( @$listref ) { - my ($decoded_file, $mime, $on_disk, $description) = @$pairref; - - - # Size check - mysql has a maximum space for the data ? - $maxsize = 1047552; # should be queried by a system( "mysqld --help" );, - # but this seems not to be supported by all current mysql-versions - - # Read data file binary - if( $on_disk ) { - if( open( FILE, "$decoded_file" )) { - binmode FILE; - read FILE, $data, $maxsize; - close FILE; - $att_count ++; - } else { - print "Error while reading attachment $decoded_file!\n"; - next; - } - # print "unlinking $datadir/mimedump-tmp/$decoded_file"; - # unlink "$datadir/mimedump-tmp/$decoded_file"; - } else { - # data is in the scalar - $data = $decoded_file; - } - my @values = ($bugid, $timestamp, $description, $mime, $decoded_file, $submitter_id); - - unless ($test) { - $sth_attach->execute(@values); - $sth_data->execute($data); - } - } - - return( $att_count ); -} - - - -############################################################### -# Beautification -sub horLine( ) -{ - return( "-----------------------------------------------------------------------\n" ); -} - - -############################################################### -# Check if $Name is in $GroupName - -sub CheckPermissions { - my ($GroupName, $Name) = @_; - - return findUser($Name); -} - -############################################################### -# Check if component is valid for product. -sub CheckVersion { - my $Product = shift; - my $Version = shift; - my $dbh = Bugzilla->dbh; - - my $version_value = $dbh->selectrow_array(q{SELECT value - FROM versions - INNER JOIN products - ON versions.product_id = products.id - WHERE products.name= ? - AND value= ?}, undef, $Product, $Version); - return $version_value || ""; -} - -############################################################### -# Reply to a mail. -sub Reply( $$$$ ) { - my ($Sender, $MessageID, $Subject, $Text) = @_; - - - die "Cannot find sender-email-address" unless defined( $Sender ); - - if( $test ) { - open( MAIL, '>>', bz_locations()->{'datadir'} . "/bug_email_test.log" ); - } - else { - open( MAIL, "| /usr/sbin/sendmail -t" ); - } - - print MAIL "To: $Sender\n"; - print MAIL "From: Bugzilla Mailinterface<yourmail\@here.com>\n"; - print MAIL "Subject: $Subject\n"; - print MAIL "In-Reply-To: $MessageID\n" if ( defined( $MessageID )); - print MAIL "\n"; - print MAIL "$Text"; - close( MAIL ); - -} - - -############################################################### -# getEnumList -# Queries the Database for the table description and figures the -# enum-settings out - useful for checking fields for enums like -# prios -sub getEnumList( $ ) -{ - my $dbh = Bugzilla->dbh; - my ($fieldname) = @_; - my $result = $dbh->selectcol_arrayref(qq{SELECT value FROM $fieldname}); - - return($result); -} - -############################################################### -# CheckPriority -# Checks, if the priority setting is one of the enums defined -# in the data base -# Uses the global var. $Control{ 'priority' } -sub CheckPriority -{ - my $prio = $Control{'priority'}; - my $all_prios = getEnumList( "priority" ); - - if( $prio eq "" || (lsearch( $all_prios, $prio ) == -1) ) { - # OK, Prio was not defined - create Answer - my $Text = "You sent wrong priority-setting, valid values are:" . - join( "\n\t", @$all_prios ) . "\n\n"; - $Text .= "* The priority is set to the default value ". - Bugzilla->params->{'defaultpriority'} . "\n"; - - BugMailError( 0, $Text ); - - # set default value from param-file - $Control{'priority'} = Bugzilla->params->{ 'defaultpriority' }; - } else { - # Nothing to do - } -} - -############################################################### -# CheckSeverity -# checks the bug_severity -sub CheckSeverity -{ - my $sever = ($Control{'bug_severity'} ||= "" ); - my $all_sever = getEnumList( "bug_severity" ); - - if( (lsearch($all_sever, $sever) == -1) || $sever eq "" ) { - # OK, Prio was not defined - create Answer - my $Text = "You sent wrong bug_severity-setting, valid values are:" . - join( "\n\t", @$all_sever ) . "\n\n"; - $Text .= "* The bug_severity is set to the default value 'normal' \n"; - - BugMailError( 0, $Text ); - - # set default value from param-file - $Control{'bug_severity'} = "normal"; - } -} - -############################################################### -# CheckArea -# checks the area-field -sub CheckArea -{ - my $area = ($Control{'area'} ||= "" ); - my $all = getEnumList( "area" ); - - if( (lsearch($all, $area) == -1) || $area eq "" ) { - # OK, Area was not defined - create Answer - my $Text = "You sent wrong area-setting, valid values are:" . - join( "\n\t", @$all ) . "\n\n"; - $Text .= "* The area is set to the default value 'BUILD' \n"; - - BugMailError( 0, $Text ); - - # set default value from param-file - $Control{'area'} = "BUILD"; - } -} - -############################################################### -# CheckPlatform -# checks the given Platform and corrects it -sub CheckPlatform -{ - my $platform = ($Control{'rep_platform'} ||= "" ); - my $all = getEnumList( "rep_platform" ); - - if( (lsearch($all, $platform) == -1) || $platform eq "" ) { - # OK, Prio was not defined - create Answer - my $Text = "You sent wrong platform-setting, valid values are:" . - join( "\n\t", @$all ) . "\n\n"; - $Text .= "* The rep_platform is set to the default value 'All' \n"; - - BugMailError( 0, $Text ); - - # set default value from param-file - $Control{'rep_platform'} = "All"; - } -} - -############################################################### -# CheckSystem -# checks the given Op-Sys and corrects it -sub CheckSystem -{ - my $sys = ($Control{'op_sys'} ||= "" ); - my $all = getEnumList( "op_sys" ); - - if( (lsearch( $all, $sys ) == -1) || $sys eq "" ) { - # OK, Prio was not defined - create Answer - my $Text = "You sent wrong OS-setting, valid values are:" . - join( "\n\t", @$all ) . "\n\n"; - $Text .= "* The op_sys is set to the default value 'Linux' \n"; - - BugMailError( 0, $Text ); - - # set default value from param-file - $Control{'op_sys'} = "Linux"; - } -} - -############################################################### -# Error Handler for Errors in the mail -# -# This function can be called multiple within processing one mail and -# stores the errors found in the Mail. Errors are for example empty -# required tags, missing required tags and so on. -# -# The benefit is, that the mail users get a reply, where all mail errors -# are reported. The reply mail includes all messages what was wrong and -# the second mail the user sends can be ok, cause all his faults where -# reported. -# -# BugMailError takes two arguments: The first one is a flag, how heavy -# the error is: -# -# 0 - It's an error, but Bugzilla can process the bug. The user should -# handle that as a warning. -# -# 1 - It's a real bug. Bugzilla can't store the bug. The mail has to be -# resent. -# -# 2 - Permission error: The user does not have the permission to send -# a bug. -# -# The second argument is a Text which describes the bug. -# -# -# # -sub BugMailError($ $ ) -{ - my ( $errflag, $text ) = @_; - - # On permission error, don't sent all other Errors back -> just quit ! - if( $errflag == 2 ) { # Permission-Error - Reply( $SenderShort, $Message_ID, "Bugzilla Error", "Permission denied.\n\n" . - "You do not have the permissions to create a new bug. Sorry.\n" ); - exit; - } - - - # Warnings - store for the reply mail - if( $errflag == 0 ) { - push( @mailwarnings, $text ); - } - - # Critical Error - if( $errflag == 1 ) { - $critical_err += 1; - push( @mailerrors, $text ); - } -} - -############################################################### -# getWarningText() -# -# getWarningText() returns a reply-ready Textline of all the -# Warnings in the Mail -sub getWarningText() -{ - my $anz = @mailwarnings; - - my $ret = <<END - -The Bugzilla Mail Interface found warnings (JFYI): - -END - ; - - # Handshake if no warnings at all - return( "\n\n Your mail was processed without Warnings !\n" ) if( $anz == 0 ); - - # build a text - $ret .= join( "\n ", @mailwarnings ); - return( horLine() . $ret ); -} - -sub getErrorText() -{ - my $anz = @mailerrors; - - my $ret = <<END - -************************** ERROR ************************** - -Your request to the Bugzilla mail interface could not be met -due to errors in the mail. We will find it ! - - -END - ; - return( "\n\n Your mail was processed without errors !\n") if( $anz == 0 ); - # build a text - $ret .= join( "\n ", @mailerrors ); - return( $ret ); -} - -############################################################### -# generateTemplate -# -# This function generates a mail-Template with the -sub generateTemplate() -{ - my $w; - my $ret; - - # Required Labels - $ret =<<EOF - - -You may want to use this template to resend your mail. Please fill in the missing -keys. - -_____ snip _______________________________________________________________________ - -EOF - ; - foreach ( @RequiredLabels ) { - $w = ""; - $w = $Control{$_} if defined( $Control{ $_ } ); - $ret .= sprintf( " \@%-15s: %s\n", $_, $w ); - } - - $ret .= "\n"; - # Allowed Labels - foreach( @AllowedLabels ) { - next if( /reporter/ ); # Reporter is not a valid label - next if( /assigned_to/ ); # Assigned to is just a number - if( defined( $Control{ $_ } ) && lsearch( \@RequiredLabels, $_ ) == -1 ) { - $ret .= sprintf( " \@%-15s: %s\n", $_, $Control{ $_ } ); - } - } - - if( $Body eq "" ) { - $ret .= <<END - - < the bug-description follows here > - -_____ snip _______________________________________________________________________ - -END - ; } else { - $ret .= "\n" . $Body; - } - - return( $ret ); - -} -#------------------------------ -# -# dump_entity ENTITY, NAME -# -# Recursive routine for parsing a mime coded mail. -# One mail may contain more than one mime blocks, which need to be -# handled. Therefore, this function is called recursively. -# -# It gets the for bugzilla important information from the mailbody and -# stores them into the global attachment-list @attachments. The attachment-list -# is needed in storeAttachments. -# -sub dump_entity { - my ($entity, $name) = @_; - defined($name) or $name = "'anonymous'"; - my $IO; - - - # Output the body: - my @parts = $entity->parts; - if (@parts) { # multipart... - my $i; - foreach $i (0 .. $#parts) { # dump each part... - dump_entity($parts[$i], ("$name, part ".(1+$i))); - } - } else { # single part... - - # Get MIME type, and display accordingly... - my $msg_part = $entity->head->get( 'Content-Disposition' ); - - $msg_part ||= ""; - - my ($type, $subtype) = split('/', $entity->head->mime_type); - my $body = $entity->bodyhandle; - my ($data, $on_disk ); - - if( $msg_part =~ /^attachment/ ) { - # Attached File - my $des = $entity->head->get('Content-Description'); - $des ||= $entity->head->recommended_filename; - $des ||= "unnamed attachment"; - - if( defined( $body->path )) { # Data is on disk - $on_disk = 1; - $data = $body->path; - - } else { # Data is in core - $on_disk = 0; - $data = $body->as_string; - } - push ( @attachments, [ $data, $entity->head->mime_type, $on_disk, $des ] ); - } else { - # Real Message - if ($type =~ /^(text|message)$/) { # text: display it... - if ($IO = $body->open("r")) { - $Body .= $_ while (defined($_ = $IO->getline)); - $IO->close; - } else { # d'oh! - print "$0: couldn't find/open '$name': $!"; - } - } else { print "Oooops - no Body !\n"; } - } - } -} - -############################################################### -# sub extractControls -############################################################### -# -# This sub parses the message Body and filters the control-keys. -# Attention: Global hash Controls affected -# -sub extractControls( $ ) -{ - my ($body) = @_; - my $backbody = ""; - - my @lbody = split( /\n/, $body ); - - # In restricted mode, all lines before the first keyword - # are skipped. - if( $restricted ) { - while( $lbody[0] =~ /^\s*\@.*/ ){ shift( @lbody );} - } - - # Filtering for keys - foreach( @lbody ) { - if( /^\s*\@description/ ) { - s/\s*\@description//; - $backbody .= $_; - } elsif( /^\s*\@(.*?)(?:\s*=\s*|\s*:\s*|\s+)(.*?)\s*$/ ) { - $Control{lc($1)} = $2; - } else { - $backbody .= "$_" . "\n"; - } - } - - # that's it. - return( $backbody ); -} - -############################################################### -# Main starts here -############################################################### -# -# Commandline switches: -# -t: test mode - no DB-Inserts -foreach( @ARGV ) { - $restricted = 1 if ( /-r/ ); - $test = 1 if ( /-t/ ); - - if ( /-p=['"]?(.+)['"]?/ ) - { - $DEFAULT_PRODUCT = $1; - } - - if ( /-c=['"]?(.+)["']?/ ) - { - $DEFAULT_COMPONENT = $1; - } - - if ( /-v=['"]?(.+)["']?/ ) - { - $DEFAULT_VERSION = $1; - } - -} - -# -# Parsing a mime-message -# -if( -t STDIN ) { -print STDERR <<END - Bugzilla Mail Interface - - This scripts reads a mail message through stdin and parses the message, - for to insert a bug to bugzilla. - - Options - -t: Testmode - No insert to the DB, but logfile - -r: restricted mode - all lines before the keys in the mail are skipped - -END - ; -exit; -} - - -# Create a new MIME parser: -my $parser = new MIME::Parser; - -# Create and set the output directory: -# FIXME: There should be a $BUGZILLA_HOME variable (SML) -my $datadir = bz_locations()->{'datadir'}; -(-d "$datadir/mimedump-tmp") or mkdir "$datadir/mimedump-tmp",0755 or die "mkdir: $!"; -(-w "$datadir/mimedump-tmp") or die "can't write to directory"; - -$parser->output_dir("$datadir/mimedump-tmp"); - -# Read the MIME message: -my $entity = $parser->read(\*STDIN) or die "couldn't parse MIME stream"; -$entity->remove_sig(10); # Removes the signature in the last 10 lines - -# Getting values from parsed mail -my $Sender = $entity->get( 'From' ); -$Sender ||= $entity->get( 'Reply-To' ); -$Message_ID = $entity->get( 'Message-Id' ); - -die (" *** Can't find Sender-address in sent mail ! ***\n" ) unless defined( $Sender ); -chomp( $Sender ); -chomp( $Message_ID ); - -$SenderShort = $Sender; -$SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/; - -$SenderShort = findUser($SenderShort); - -if (!defined($SenderShort)) { - $SenderShort = $Sender; - $SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/; -} - -my $Subject = ""; -$Subject = $entity->get( 'Subject' ); -chomp( $Subject ); - -# Get all the attachments -dump_entity($entity); -# print $Body; -$Body = extractControls( $Body ); # fills the Control-Hash - -if( $test ) { - foreach (keys %Control ) { - print "$_ => $Control{$_}\n"; - } -} - -$Control{'short_desc'} ||= $Subject; -# -# * Mailparsing finishes here * -# - -###################################################################### -# Now a lot of Checks of the given Labels start. -# Check Control-Labels -# not: reporter ! -@AllowedLabels = ("product", "version", "rep_platform", - "bug_severity", "priority", "op_sys", "assigned_to", - "bug_status", "bug_file_loc", "short_desc", "component", - "status_whiteboard", "target_milestone", "groupset", - "qa_contact"); -#my @AllowedLabels = qw{Summary priority platform assign}; -foreach (keys %Control) { - if ( lsearch( \@AllowedLabels, $_) < 0 ) { - BugMailError( 0, "You sent a unknown label: " . $_ ); - } -} - -push( @AllowedLabels, "reporter" ); -$Control{'reporter'} = $SenderShort; - -# Check required Labels - not all labels are required, because they could be generated -# from the given information -# Just send a warning- the error-Flag will be set later -@RequiredLabels = qw{product version component short_desc}; -foreach my $Label (@RequiredLabels) { - if ( ! defined $Control{$Label} ) { - BugMailError( 0, "You were missing a required label: \@$Label\n" ); - next; - } - - if( $Control{$Label} =~ /^\s*$/ ) { - BugMailError( 0, "One of your required labels is empty: $Label" ); - next; - } -} - -if ( $Body =~ /^\s*$/s ) { - BugMailError( 1, "You sent a completely empty body !" ); -} - - -# umask 0; - -# Check Permissions ... -if (! CheckPermissions("CreateBugs", $SenderShort ) ) { - BugMailError( 2, "Permission denied.\n\n" . - "You do not have the permissions to create a new bug. Sorry.\n" ); -} - -# Set QA -if (Bugzilla->params->{"useqacontact"}) { - if (defined($Control{'qa_contact'}) - && $Control{'qa_contact'} !~ /^\s*$/ ) { - $Control{'qa_contact'} = DBname_to_id($Control{'qa_contact'}); - } else { - $Control{'qa_contact'} = $dbh->selectrow_array(q{ - SELECT initialqacontact - FROM components - INNER JOIN products - ON components.product_id = products.id - WHERE products.name = ? - AND components.name = ?}, - undef, $Control{'product'}, $Control{'component'}); - } -} - -# Set Assigned - assigned_to depends on the product, cause initialowner -# depends on the product ! -# => first check product ! -# Product -my $product; -my $all_products; -# set to the default product. If the default product is empty, this has no effect -my $Product = $DEFAULT_PRODUCT; -if (defined($Control{ 'product'})) { - $product = new Bugzilla::Product({'name' => $Control{'product'}}); - $Product = $product ? $product->name : ""; -} - -if ( $Product eq "" ) { - my $Text = "You didn't send a value for the required key \@product !\n\n"; - - $Text = "You sent the invalid product \"$Control{'product'}\"!\n\n" - if( defined( $Control{ 'product'} )); - - $Text .= "Valid products are:\n\t"; - $all_products = $dbh->selectcol_arrayref(q{SELECT name - FROM products - ORDER BY name}); - $Text .= join( "\n\t", @$all_products ) . "\n\n"; - $Text .= horLine(); - - BugMailError( 1, $Text ); -} else { - # Fill list @all_products, which is needed in case of component-help - @$all_products = ( $Product ); - $product_valid = 1; -} -$Control{'product'} = $Product; - -# -# Check the Component: -# - -# set to the default component. If the default component is empty, this has no effect -my $component; -my $Component = $DEFAULT_COMPONENT; - -if (defined($Control{'component'})) { - $component = new Bugzilla::Component({'product_id' => $product->id, - 'name' => $Control{'component'}}); - $Component = $component ? $component->name : ""; -} - -if ( $Component eq "" ) { - - my $Text = "You did not send a value for the required key \@component!\n\n"; - - if( defined( $Control{ 'component' } )) { - $Text = "You sent the invalid component \"$Control{'component'}\" !\n"; - } - - # - # Attention: If no product was sent, the user needs info for all components of all - # products -> big reply mail :) - # if a product was sent, only reply the components of the sent product - my $val_components; - my $sth_comp = $dbh->prepare(q{SELECT components.name - FROM components - INNER JOIN products - ON components.product_id = products.id - WHERE products.name = ?}); - foreach my $prod ( @$all_products ) { - $Text .= "\nValid components for product `$prod' are: \n\t"; - - $val_components = $dbh->selectcol_arrayref($sth_comp, undef, $prod); - - $Text .= join( "\n\t", @$val_components ) . "\n"; - } - - # Special: if there is a valid product, maybe it has only one component -> use it ! - # - my $amount_of_comps = scalar(@$val_components); - if( $product_valid && $amount_of_comps == 1 ) { - $Component = @$val_components[0]; - - $Text .= " * You did not send a component, but a valid product $Product.\n"; - $Text .= " * This product only has one component $Component.\n" . - " * This component was set by bugzilla for submitting the bug.\n\n"; - BugMailError( 0, $Text ); # No blocker - - } else { # The component is really buggy :( - $Text .= horLine(); - BugMailError( 1, $Text ); - } -} -$Control{'component'} = $Component; - - -# -# Check assigned_to -# If a value was given in the e-mail, convert it to an ID, -# otherwise, retrieve it from the database. -if ( defined($Control{'assigned_to'}) - && $Control{'assigned_to'} !~ /^\s*$/ ) { - $Control{'assigned_to'} = login_to_id($Control{'assigned_to'}); -} else { - $Control{'assigned_to'} = $dbh->selectrow_array(q{ - SELECT initialowner - FROM components - INNER JOIN products - ON components.product_id=products.id - WHERE products.name= ? - AND components.name= ?}, - undef, $Control{'product'}, $Control{'component'}); -} - -if ( $Control{'assigned_to'} == 0 ) { - my $Text = "Could not resolve key \@assigned_to !\n" . - "If you do NOT send a value for assigned_to, the bug will be assigned to\n" . - "the qa-contact for the product and component.\n"; - $Text .= "This works only if product and component are OK. \n" - . horLine(); - - BugMailError( 1, $Text ); -} - - -$Control{'reporter'} = login_to_id($Control{'reporter'}); -if ( ! $Control{'reporter'} ) { - BugMailError( 1, "Could not resolve reporter !\n" ); -} - -### Set default values -CheckPriority( ); -CheckSeverity( ); -CheckPlatform( ); -CheckSystem( ); -# CheckArea(); - -### Check values ... -# Version -my $Version = "$DEFAULT_VERSION"; -$Version = CheckVersion( $Control{'product'}, $Control{'version'} ) if( defined( $Control{'version'})); -if ( $Version eq "" ) { - my $Text = "You did not send a value for the required key \@version!\n\n"; - - if( defined( $Control{'version'})) { - my $Text = "You sent the invalid version \"$Control{'version'}\"!\n"; - } - - my $anz_versions; - my @all_versions; - # Assemble help text - my $sth_versions = $dbh->prepare(q{SELECT value - FROM versions - INNER JOIN products - ON versions.product_id = products.id - WHERE products.name= ?}); - - foreach my $prod ( @$all_products ) { - $Text .= "Valid versions for product $prod are: \n\t"; - - @all_versions = @{$dbh->selectcol_arrayref($sth_versions, undef, $prod)}; - $anz_versions = @all_versions; - $Text .= join( "\n\t", @all_versions ) . "\n" ; - - } - - # Check if we could use the only version - if( $anz_versions == 1 && $product_valid ) { - $Version = $all_versions[0]; - # Fine, there is only one version string - $Text .= " * You did not send a version, but a valid product $Product.\n"; - $Text .= " * This product has has only the one version $Version.\n" . - " * This version was set by bugzilla for submitting the bug.\n\n"; - $Text .= horLine(); - BugMailError( 0, $Text ); # No blocker - } else { - $Text .= horLine(); - BugMailError( 1, $Text ); - } - -} - -$Control{'version'} = $Version; - -# GroupsSet: Protections for Bug info. This parameter controls the visibility of the -# given bug. An Error in the given Buggroup is not a blocker, a default is taken. -# -# The GroupSet is accepted only as literals linked with whitespaces, plus-signs or commas -# -my $GroupSet = ""; -my %GroupArr = (); -$GroupSet = $Control{'groupset'} if( defined( $Control{ 'groupset' })); -# -# Fetch the default value for groupsetting -my $DefaultGroup = 'ReadInternal'; - -my $default_group = $dbh->selectrow_array(q{ - SELECT id - FROM groups - WHERE name= ?}, undef, $DefaultGroup); - -if( $GroupSet eq "" ) { - # Too bad: Groupset does not contain anything -> set to default - $GroupArr{$DefaultGroup} = $default_group if(defined( $default_group )); - # - # Give the user a hint - my $Text = "You did not send a value for optional key \@groupset, which controls\n"; - $Text .= "the Permissions of the bug. It will be set to a default value 'Internal Bug'\n"; - $Text .= "if the group '$DefaultGroup' exists. The QA may change that.\n"; - - BugMailError( 0, $Text ); -} else { - # literal e.g. 'ReadInternal' - my $gserr = 0; - my $Text = ""; - - # - # Split literal Groupsettings either on Whitespaces, +-Signs or , - # Then search for every Literal in the DB - col name - my $sth_groups = $dbh->prepare(q{SELECT id, name - FROM groups - WHERE name= ?}); - foreach ( split /\s+|\s*\+\s*|\s*,\s*/, $GroupSet ) { - my( $bval, $bname ) = $dbh->selectrow_array($sth_groups, undef, $_); - if( defined( $bname ) && $_ eq $bname ) { - $GroupArr{$bname} = $bval; - } else { - $Text .= "You sent the wrong GroupSet-String $_\n"; - $gserr = 1; - } - } - - # - # Give help if wrong GroupSet-String came - if( $gserr > 0 ) { - # There happend errors - $Text .= "Here are all valid literal Groupsetting-strings:\n\t"; - my $groups = $dbh->selectcol_arrayref(q{ - SELECT g.name - FROM groups g - INNER JOIN user_group_map u - ON g.id = u.group_id - WHERE u.user_id = ? - AND g.isbuggroup = 1 } . - $dbh->sql_group_by('g.name'), undef, $Control{'reporter'}); - $Text .= join( "\n\t", @$groups ) . "\n"; - BugMailError( 0, $Text ); - } -} # End of checking groupsets -delete $Control{'groupset'}; - -# ################################################################################### -# Checking is finished -# - -# Check used fields -my @used_fields; - -foreach my $f (@AllowedLabels) { - if ((exists $Control{$f}) && ($Control{$f} !~ /^\s*$/ )) { - push (@used_fields, $f); - } -} - -# -# Creating the query for inserting the bug -# -> this should only be done, if there was no critical error before -if( $critical_err == 0 ) -{ - - my $reply = <<END - - +---------------------------------------------------------------------------+ - B U G Z I L L A - M A I L - I N T E R F A C E - +---------------------------------------------------------------------------+ - - Your Bugzilla Mail Interface request was successfull. - -END -; - - $reply .= "Your Bug-ID is "; - my $reporter = ""; - - - - my $tmp_reply = "These values were stored by bugzilla:\n"; - my $val; - my @values = (); - foreach my $field (@used_fields) { - if( $field eq "groupset" ) { - push (@values, $Control{$field}); - } elsif ( $field eq 'product' ) { - push (@values, $product->id); - } elsif ( $field eq 'component' ) { - push (@values, $component->id); - } else { - push (@values, $Control{$field}); - } - - $val = $Control{ $field }; - - $val = user_id_to_login( $val ) if( $field =~ /reporter|assigned_to|qa_contact/ ); - - $tmp_reply .= sprintf( " \@%-15s = %-15s\n", $field, $val ); - - if ($field eq "reporter") { - $reporter = $val; - } - } - # - # Display GroupArr - # - $tmp_reply .= sprintf( " \@%-15s = %-15s\n", 'groupset', join(',', keys %GroupArr) ); - - $tmp_reply .= " ... and your error-description !\n"; - - my $comment = $Body; - $comment =~ s/\r\n/\n/g; # Get rid of windows-style line endings. - $comment =~ s/\r/\n/g; # Get rid of mac-style line endings. - $comment = trim($comment); - - my $bug_when = $dbh->selectrow_array("SELECT NOW()"); - - my $ever_confirmed = 0; - my $state = "UNCONFIRMED"; - - my $v_confirm = $dbh->selectrow_array(q{SELECT votestoconfirm - FROM products - WHERE name = ?}, undef, $Control{'product'}); - if (!$v_confirm) { - $ever_confirmed = 1; - $state = "NEW"; - } - - my $sql_placeholders = "?, " x scalar(@values); - my $sql_used_fields = join(", ", @used_fields); - - my $query = qq{INSERT INTO bugs ($sql_used_fields, bug_status, - creation_ts, delta_ts, everconfirmed) - VALUES ($sql_placeholders ?, ?, ?, ? )}; - - $query =~ s/product/product_id/; - $query =~ s/component/component_id/; - - push (@values, $state, $bug_when, $bug_when, $ever_confirmed); - - my $userid = $dbh->selectrow_array(q{SELECT userid FROM profiles WHERE } . - $dbh->sql_istrcmp('login_name', '?'), - undef, $reporter); - - my $id; - if( ! $test ) { - - $dbh->do($query, undef, @values); - $id = $dbh->bz_last_key('bugs', 'bug_id'); - - $dbh->do(q{INSERT INTO longdescs - SET bug_id= ?, who= ?, bug_when= ?, thetext= ?}, - undef, $id, $userid, $bug_when, $comment); - - # Cool, the mail was successful - # system("./processmail", $id, $SenderShort); - } else { - $id = 0xFFFFFFFF; # TEST ! - print "\n-------------------------------------------------------------------------\n"; - print "$query\n"; - } - - # - # Handle GroupArr - # - my $sth_groups = $dbh->prepare(q{INSERT INTO bug_group_map SET bug_id= ?, group_id= ?}); - foreach my $grp (keys %GroupArr) { - if( ! $test) { - $sth_groups->execute($id, $GroupArr{$grp}); - } else { - print "INSERT INTO bug_group_map SET bug_id=$id, group_id=$GroupArr{$grp}\n"; - } - } - - # - # handle Attachments - # - my $attaches = storeAttachments( $id, $Control{'reporter'} ); - $tmp_reply .= "\n\tYou sent $attaches attachment(s). \n" if( $attaches > 0 ); - - $reply .= $id . "\n\n" . $tmp_reply . "\n" . getWarningText(); - $entity->purge(); # Removes all temp files - - # - # Send the 'you did it'-reply - Reply( $SenderShort, $Message_ID,"Bugzilla success (ID $id)", $reply ); - - Bugzilla::BugMail::Send($id, {'changer' => $reporter}) if (!$test); - -} else { - # There were critical errors in the mail - the bug couldn't be inserted. ! -my $errreply = <<END - - +---------------------------------------------------------------------------+ - B U G Z I L L A - M A I L - I N T E R F A C E - +---------------------------------------------------------------------------+ - -END - ; - - $errreply .= getErrorText() . getWarningText() . generateTemplate(); - - Reply( $SenderShort, $Message_ID, "Bugzilla Error", $errreply ); - - # print getErrorText(); - # print getWarningText(); - # print generateTemplate(); -} - - - - - -exit; - diff --git a/contrib/bugmail_help.html b/contrib/bugmail_help.html deleted file mode 100644 index 2d6426510..000000000 --- a/contrib/bugmail_help.html +++ /dev/null @@ -1,223 +0,0 @@ -<HTML> -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<!-- - The contents of this file are subject to the Mozilla Public - License Version 1.1 (the "License"); you may not use this file - except in compliance with the License. You may obtain a copy of - the License at http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. See the License for the specific language governing - rights and limitations under the License. - - The Original Code is the Bugzilla Bug Tracking System. - - Contributor(s): Klaas Freitag <Freitag@SuSE.de> ---> - -<HEAD> <TITLE>Bugzilla Mail Interface</TITLE> </HEAD> -<BODY BGCOLOR="#FFFFFF"> -<CENTER><H1>The Bugzilla Mail Interface</H1> -Contributor: <A HREF="mailto:freitag@suse.de">Klaas Freitag</A>, SuSE GmbH -</CENTER> -<P> -The bugzilla Mail interface allows the registered bugzilla users to submit bugs by -sending email with a bug description. This is useful for people, who do not work -inhouse and want to submitt bugs to the bugzilla system. -<p> - - -I know, show me the <A HREF="#examplemail">example-mail !</A> - - -<H2>What do you need to do to submitt a bug by mail ?</H2> -You need to send a email in the described format to the bugmail-user of the -bugzilla-system. This is <A HREF="mailto:our_bugzilla@xyz.com">yourbugzilla@here.com</A> - -You receive a reply mail with the new bug-ID if your request was ok. -If not, you get a mail with -some help on the bugmail system and a specific analysis of your request. -<P> -Please don't refuse to send one or two wrong mails, you will get all the information -you need in the replies, and <I>only</I> in the mail replies. The information on this -page, concerning available products, versions and so on, is not dynamicly generated and -may be old therefore. - -<H1>The Mail Format</H1> -The bugmail needs a special format , which consists of some keywords and suitable -values for them and a description text. Note that the keyword block needs to be -above of the description text. - -<H2>Keywords</H2> -You need to tell bugzilla some properties of the bugs. This is done by keywords, which -start on a new line with a @, followed by the keyword and and equal-sign, followed by a -hopefully valid value. - - -<TABLE BORDER=4 FRAME=box CELLSPACING="5" width=95%> <COLGROUP> <col width="2*"> -<col width="5*"> <col width="1*"> </COLGROUP> - <TR> - <TH>Keyword</TH> - <TH>Value description</TH> - <TH>required and default value</TH> - </TR> - <TR> - <TD>@product</TD> - <TD>The product which has a bug</TD> - <TD>yes. <br> This is the most important information. Many other - fields depend on the product.</TD> - </TR> - <TR> - <TD>@component</TD> - <TD>the desired component which is affected by the bug</TD> - <TD>yes. <br> As the @product, this is a very important - field.</TD> - </TR> - <TR> - <TD>@version</TD> - <TD>The version of the product</TD> - <TD>yes. <br>See @product and @component</TD> - </TR> - <TR> - <TD>@short_desc</TD> - <TD>A summary of your bug report</TD> - <TD>yes. <br>This summary of the error you want to report - describes what happen. You may skip the long description, - but not this summary.<br> - <b>Note:</b>The short description may be given in the mail subject - instead of using the keyword !</TD> - </TR> - <TR> - <TD>@rep_platform</TD> - <TD>The desired platform</TD> - <TD>no.<br>If you don't give a value, this field is set to <I>All</I>.</TD> - </TR> - <TR> - <TD>@bug_severity</TD> - <TD>The severity of the bug</TD> - <TD>no. <br> If you don't give a value, this field is set to - <I>normal</I></TD> - </TR> - <TR> - <TD>@priority</TD> - <TD>The priority of the bug</TD> - <TD>no.<br>If you don't give a value, this field is set to <I>P3</I></TD> - </TR> - <TR> - <TD>@op_sys</TD> - <TD>The operating system</TD> - <TD>no.<br>If you don't give a value, this field is set to <I>Linux</I>.</TD> - </TR> - <TR> - <TD>@assigned_to</TD> - <TD>The one to whom the bug is assigned to</TD> - <TD>no. <br>There is a default assignee for every product/version/component. - He owns the bug by default. The default assignee can only be found if - product, version and component are valid.</TD> - </TR> - <TR> - <TD>@bug_file_loc</TD> - <TD>?</TD> - <TD>no.</TD> - </TR> - <TR> - <TD>@status_whiteboard</TD> - <TD>?</TD> - <TD>no.</TD> - </TR> - <TR> - <TD>@target_milestone</TD> - <TD>?</TD> - <TD>no.</TD> - </TR> - <TR> - <TD>@groupset</TD> - <TD>rules the visibility of the bug.</TD> - <TD>no.<br>This value defaults to the smallest of the available groups, - which is <I>readInternal</I>.</TD> - </TR> - <TR> - <TD>@qa_contact</TD> - <TD>the quality manager for the product</TD> - <TD>no.<br>This value can be retrieved from product, component and - version</TD> - </TR> - -</TABLE> -<H2>Valid values</H2> -Give string values for the most keys above. Some keywords require special values:<br> -<ol> -<li>E-Mail addresses: If you want to set the qa-contact, specify an email-address for @qa_contact. The email must be known by bugzilla of course.</li> -<li>Listvalues: Most of the values have to be one of a list of valid values. Try by sending -a mail and read the reply. Skip fields if you don't get help for them unless you don't know -which values you may choose.</li> -<li>free Text: The descriptions may be free text. </li> -<li>Special: The field groupset may be specified in different in three different kinds: - <ol> - <li> A plain numeric way, which is one usually huge number, e. g. <I>65536</I></li> - <li> a string with added numbers e.g. <I>65536+131072</I></li> - <li> a string list, e.g. <I>ReadInternal, ReadBeta </I></li> - </ol> -</li> -</ol> - -<p> - -But most of them need <b>valid</b> values. -<p> -Sorry, you will not find lists of valid products, components and the other stuff -here. Send a mail to with any text, and you will get a list of valid keywords in the reply. - -<p> -Some of the values must be choosen from a list:<br> -<ol> - <li>bug_severity: blocker, critical, major, normal, minor, trivial, enhancement</li> - <li>op_sys: Linux </li> - <li>priority: P1, P2, P3, P4, P5</li> - <li>rep_platform: All, i386, AXP, i686, Other</li></ol> - - -<p> - -After you have specified the required keywords and maybe some other value, you may -describe your bug. You don't need a keyword for starting your bug description. All -text which follows the keyword block is handled as long description of the bug. -<p> - -The bugmail interface is able to find required information by itself. E.g. if you specify -a product which has exactly one component, this component will be found by the interface -automatically. - -<H1>Attachments</H1> - -The mail interface is able to cope with MIME-attachments. -People could for example add a logfile as a mail attachment, and it will appear in -bugzilla as attachment. A comment for the attachment should be added, it will describe -the attachment in bugzilla. - -<H1><A NAME="examplemail">Example Mail</A></H1> - -See the example of the mail <b>body</b> (Don't forget to specify the short description -in the mail subject):<hr><pre> - - @product = Bugzilla - @component = general - @version = All - @groupset = ReadWorld ReadPartners - @op_sys = Linux - @priority = P3 - @rep_platform = i386 - - - This is the description of the bug I found. It is not neccessary to start - it with a keyword. - - Note: The short_description is neccessary and may be given with the keyword - @short_description or will be retrieved from the mail subject. - - -</pre><hr> - -</BODY> -</HTML> diff --git a/contrib/bugzilla.procmailrc b/contrib/bugzilla.procmailrc deleted file mode 100644 index 36656b4d2..000000000 --- a/contrib/bugzilla.procmailrc +++ /dev/null @@ -1,30 +0,0 @@ -:0 fhw -| formail -I "From " -a "From " - -BUGZILLA_HOME=/home/bugzilla/WEB/bugzilla/contrib - -:0 -* ^Subject: .*\[Bug .*\] -RESULT=|(cd $BUGZILLA_HOME && ./bugzilla_email_append.pl) - - -# Feed mail to stdin of bug_email.pl -:0 Ec -#* !^Subject: .*[Bug .*] -RESULT=|(cd $BUGZILLA_HOME && ./bug_email.pl ) - -# write result to a logfile -:0 c -|echo `date '+%d.%m.%y %H:%M: '` $RESULT >> $HOME/bug_email.log - - -:0 c -|echo "----------------------------------" >> $HOME/bug_email.log - -:0 c -$HOME/bug_email.log - -# Move mail to the inbox -:0 -$HOME/Mail/INBOX - diff --git a/contrib/bugzilla_email_append.pl b/contrib/bugzilla_email_append.pl deleted file mode 100755 index 4b2e53f20..000000000 --- a/contrib/bugzilla_email_append.pl +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/perl -w -# -*- Mode: perl; indent-tabs-mode: nil -*- - -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. - -# The purpose of this script is to take an email message, which -# specifies a bugid and append it to the bug as part of the longdesc -# table - -# Contributor : Seth M. Landsman <seth@dworkin.net> - -# 03/15/00 : Initial version by SML -# 03/15/00 : processmail gets called - -# Email subject must be of format : -# .* Bug ### .* -# replying to a typical bugzilla email should be valid - -# TODO : -# 1. better way to get the body text (I don't know what dump_entity() is -# actually doing - -use strict; -use MIME::Parser; - -BEGIN { - chdir ".."; # this script lives in contrib, change to main - push @INC, "contrib"; - push @INC, "."; # this script lives in contrib -} - -use Bugzilla; -use Bugzilla::Constants; -use BugzillaEmail; -use Bugzilla::BugMail; - -my $dbh = Bugzilla->dbh; - -# Create a new MIME parser: -my $parser = new MIME::Parser; - -my $Comment = ""; - -# Create and set the output directory: -# FIXME: There should be a $BUGZILLA_HOME variable (SML) -my $datadir = bz_locations()->{'datadir'}; -(-d "$datadir/mimedump-tmp") or mkdir "$datadir/mimedump-tmp",0755 or die "mkdir: $!"; -(-w "$datadir/mimedump-tmp") or die "can't write to directory"; - -$parser->output_dir("$datadir/mimedump-tmp"); - -# Read the MIME message: -my $entity = $parser->read(\*STDIN) or die "couldn't parse MIME stream"; -$entity->remove_sig(10); # Removes the signature in the last 10 lines - -# Getting values from parsed mail -my $Sender = $entity->get( 'From' ); -$Sender ||= $entity->get( 'Reply-To' ); -my $Message_ID = $entity->get( 'Message-Id' ); - -die (" *** Can't find Sender-address in sent mail ! ***\n" ) unless defined( $Sender ); -chomp( $Sender ); -chomp( $Message_ID ); - -print "Dealing with the sender $Sender\n"; - -my $SenderShort = $Sender; -$SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/; - -$SenderShort = findUser($SenderShort); - -print "SenderShort is $SenderShort\n"; -if (!defined($SenderShort)) { - $SenderShort = $Sender; - $SenderShort =~ s/^.*?([a-zA-Z0-9_.-]+?\@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+).*$/$1/; -} -print "The sendershort is now $SenderShort\n"; - -if (!defined($SenderShort)) { - DealWithError("No such user $SenderShort exists."); -} - -my $Subject = $entity->get('Subject'); -print "The subject is $Subject\n"; - -my ($bugid) = ($Subject =~ /\[Bug ([\d]+)\]/); -print "The bugid is $bugid\n"; - -# make sure the bug exists -my $found_id = $dbh->selectrow_array(q{SELECT bug_id - FROM bugs - WHERE bug_id = ?}, undef, $bugid); -print "Did we find the bug? $found_id-\n"; -if (!defined($found_id)) { - DealWithError("Bug $bugid does not exist"); -} - -# get the user id -my $userid = $dbh->selectrow_array(q{SELECT userid FROM profiles WHERE } . - $dbh->sql_istrcmp('login_name', '?'), undef, $SenderShort); -if (!defined($userid)) { - DealWithError("Userid not found for $SenderShort"); -} - -# parse out the text of the message -dump_entity($entity); - -# Get rid of the bug id -$Subject =~ s/\[Bug [\d]+\]//; -#my $Comment = "This is only a test ..."; -my $Body = "Subject: " . $Subject . "\n" . $Comment; - -# shove it in the table -$dbh->do(q{INSERT INTO longdescs SET bug_id= ?, who= ?, bug_when= NOW(), thetext= ? }, - undef, $found_id, $userid, $Body); - -Bugzilla::BugMail::Send( $found_id, { changer => $SenderShort } ); - -sub DealWithError { - my ($reason) = @_; - print $reason . "\n"; - exit 100; -} - -# Yanking this wholesale from bug_email, 'cause I know this works. I'll -# figure out what it really does later -#------------------------------ -# -# dump_entity ENTITY, NAME -# -# Recursive routine for parsing a mime coded mail. -# One mail may contain more than one mime blocks, which need to be -# handled. Therefore, this function is called recursively. -# -# It gets the for bugzilla important information from the mailbody and -# stores them into the global attachment-list @attachments. The attachment-list -# is needed in storeAttachments. -# -sub dump_entity { - my ($entity, $name) = @_; - defined($name) or $name = "'anonymous'"; - my $IO; - - - # Output the body: - my @parts = $entity->parts; - if (@parts) { # multipart... - my $i; - foreach $i (0 .. $#parts) { # dump each part... - dump_entity($parts[$i], ("$name, part ".(1+$i))); - } - } else { # single part... - - # Get MIME type, and display accordingly... - my $msg_part = $entity->head->get( 'Content-Disposition' ); - - $msg_part ||= ""; - - my ($type, $subtype) = split('/', $entity->head->mime_type); - my $body = $entity->bodyhandle; - my ($data, $on_disk ); - - if( $msg_part =~ /^attachment/ ) { - # Attached File - my $des = $entity->head->get('Content-Description'); - $des ||= ""; - - if( defined( $body->path )) { # Data is on disk - $on_disk = 1; - $data = $body->path; - - } else { # Data is in core - $on_disk = 0; - $data = $body->as_string; - } -# push ( @attachments, [ $data, $entity->head->mime_type, $on_disk, $des ] ); - } else { - # Real Message - if ($type =~ /^(text|message)$/) { # text: display it... - if ($IO = $body->open("r")) { - $Comment .= $_ while (defined($_ = $IO->getline)); - $IO->close; - } else { # d'oh! - print "$0: couldn't find/open '$name': $!"; - } - } else { print "Oooops - no Body !\n"; } - } - } -} |