1# -- 2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/ 3# -- 4# This software comes with ABSOLUTELY NO WARRANTY. For details, see 5# the enclosed file COPYING for license information (GPL). If you 6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. 7# -- 8 9package Kernel::System::Console::Command::Maint::PostMaster::Read; 10 11use strict; 12use warnings; 13 14use parent qw(Kernel::System::Console::BaseCommand); 15 16our @ObjectDependencies = ( 17 'Kernel::System::CommunicationLog', 18 'Kernel::System::Main', 19); 20 21sub Configure { 22 my ( $Self, %Param ) = @_; 23 24 $Self->Description('Read incoming email from STDIN.'); 25 $Self->AddOption( 26 Name => 'target-queue', 27 Description => "Preselect a target queue by name.", 28 Required => 0, 29 HasValue => 1, 30 ValueRegex => qr/.*/smx, 31 ); 32 $Self->AddOption( 33 Name => 'untrusted', 34 Description => "This will cause X-OTRS email headers to be ignored.", 35 Required => 0, 36 HasValue => 0, 37 ); 38 39 return; 40} 41 42sub Run { 43 my ( $Self, %Param ) = @_; 44 45 # start a new incoming communication 46 my $CommunicationLogObject = $Kernel::OM->Create( 47 'Kernel::System::CommunicationLog', 48 ObjectParams => { 49 Transport => 'Email', 50 Direction => 'Incoming', 51 AccountType => 'STDIN', 52 }, 53 ); 54 55 # start object log for the incoming connection 56 $CommunicationLogObject->ObjectLogStart( ObjectLogType => 'Connection' ); 57 58 $CommunicationLogObject->ObjectLog( 59 ObjectLogType => 'Connection', 60 Priority => 'Debug', 61 Key => 'Kernel::System::Console::Command::Maint::PostMaster::Read', 62 Value => 'Read email from STDIN.', 63 ); 64 65 # get email from SDTIN 66 my @Email = <STDIN>; ## no critic 67 68 if ( !@Email ) { 69 70 $CommunicationLogObject->ObjectLog( 71 ObjectLogType => 'Connection', 72 Priority => 'Error', 73 Key => 'Kernel::System::Console::Command::Maint::PostMaster::Read', 74 Value => 'Got no email on STDIN!', 75 ); 76 77 $CommunicationLogObject->ObjectLogStop( 78 ObjectLogType => 'Connection', 79 Status => 'Failed', 80 ); 81 $CommunicationLogObject->CommunicationStop( Status => 'Failed' ); 82 83 return $Self->ExitCodeError(1); 84 } 85 86 $CommunicationLogObject->ObjectLog( 87 ObjectLogType => 'Connection', 88 Priority => 'Debug', 89 Key => 'Kernel::System::Console::Command::Maint::PostMaster::Read', 90 Value => 'Email with ' . ( scalar @Email ) . ' lines successfully read from STDIN.', 91 ); 92 93 # start object log for the email processing 94 $CommunicationLogObject->ObjectLogStart( ObjectLogType => 'Message' ); 95 96 # remember the return code to stop the communictaion later with a proper status 97 my $PostMasterReturnCode = 0; 98 99 # Wrap the main part of the script in an "eval" block so that any 100 # unexpected (but probably transient) fatal errors (such as the 101 # database being unavailable) can be trapped without causing a 102 # bounce 103 eval { 104 105 $CommunicationLogObject->ObjectLog( 106 ObjectLogType => 'Message', 107 Priority => 'Debug', 108 Key => 'Kernel::System::Console::Command::Maint::PostMaster::Read', 109 Value => 'Processing email with PostMaster module.', 110 ); 111 112 my $PostMasterObject = $Kernel::OM->Create( 113 'Kernel::System::PostMaster', 114 ObjectParams => { 115 CommunicationLogObject => $CommunicationLogObject, 116 Email => \@Email, 117 Trusted => $Self->GetOption('untrusted') ? 0 : 1, 118 }, 119 ); 120 121 my @Return = $PostMasterObject->Run( 122 Queue => $Self->GetOption('target-queue'), 123 ); 124 125 if ( !$Return[0] ) { 126 127 $CommunicationLogObject->ObjectLog( 128 ObjectLogType => 'Message', 129 Priority => 'Error', 130 Key => 'Kernel::System::Console::Command::Maint::PostMaster::Read', 131 Value => 'PostMaster module exited with errors, could not process email. Please refer to the log!', 132 ); 133 $CommunicationLogObject->CommunicationStop( Status => 'Failed' ); 134 135 die "Could not process email. Please refer to the log!\n"; 136 } 137 138 my $Dump = $Kernel::OM->Get('Kernel::System::Main')->Dump( \@Return ); 139 $CommunicationLogObject->ObjectLog( 140 ObjectLogType => 'Message', 141 Priority => 'Debug', 142 Key => 'Kernel::System::Console::Command::Maint::PostMaster::Read', 143 Value => "Email processing with PostMaster module completed, return data: $Dump", 144 ); 145 146 $PostMasterReturnCode = $Return[0]; 147 }; 148 149 if ($@) { 150 151 # An unexpected problem occurred (for example, the database was 152 # unavailable). Return an EX_TEMPFAIL error to cause the mail 153 # program to requeue the message instead of immediately bouncing 154 # it; see sysexits.h. Most mail programs will retry an 155 # EX_TEMPFAIL delivery for about four days, then bounce the 156 # message.) 157 my $Message = $@; 158 159 $CommunicationLogObject->ObjectLog( 160 ObjectLogType => 'Message', 161 Priority => 'Error', 162 Key => 'Kernel::System::Console::Command::Maint::PostMaster::Read', 163 Value => "An unexpected error occurred, message: $Message", 164 ); 165 166 $CommunicationLogObject->ObjectLogStop( 167 ObjectLogType => 'Message', 168 Status => 'Failed', 169 ); 170 $CommunicationLogObject->ObjectLogStop( 171 ObjectLogType => 'Connection', 172 Status => 'Failed', 173 ); 174 $CommunicationLogObject->CommunicationStop( Status => 'Failed' ); 175 176 return $Self->ExitCodeError(75); 177 } 178 179 $CommunicationLogObject->ObjectLog( 180 ObjectLogType => 'Connection', 181 Priority => 'Debug', 182 Key => 'Kernel::System::Console::Command::Maint::PostMaster::Read', 183 Value => 'Closing connection from STDIN.', 184 ); 185 186 $CommunicationLogObject->ObjectLogStop( 187 ObjectLogType => 'Message', 188 Status => 'Successful', 189 ); 190 $CommunicationLogObject->ObjectLogStop( 191 ObjectLogType => 'Connection', 192 Status => 'Successful', 193 ); 194 195 my %ReturnCodeMap = ( 196 0 => 'Failed', # error (also false) 197 1 => 'Successful', # new ticket created 198 2 => 'Successful', # follow up / open/reopen 199 3 => 'Successful', # follow up / close -> new ticket 200 4 => 'Failed', # follow up / close -> reject 201 5 => 'Successful', # ignored (because of X-OTRS-Ignore header) 202 ); 203 204 $CommunicationLogObject->CommunicationStop( 205 Status => $ReturnCodeMap{$PostMasterReturnCode} // 'Failed', 206 ); 207 208 return $Self->ExitCodeOk(); 209} 210 2111; 212