The new library is located in library/runtime/process/notification. This allows to use it apart from the CMS.
198 lines
4.5 KiB
Plaintext
198 lines
4.5 KiB
Plaintext
note
|
|
description : "Objects that ..."
|
|
author : "$Author$"
|
|
date : "$Date$"
|
|
revision : "$Revision$"
|
|
|
|
class
|
|
NOTIFICATION_EXTERNAL_MAILER
|
|
|
|
inherit
|
|
NOTIFICATION_MAILER
|
|
|
|
-- SHARED_EXECUTION_ENVIRONMENT
|
|
|
|
create
|
|
make
|
|
|
|
feature {NONE} -- Initialization
|
|
|
|
make (a_exe: like executable_path; args: detachable ITERABLE [READABLE_STRING_8])
|
|
-- Initialize `Current'.
|
|
do
|
|
set_parameters (a_exe, args)
|
|
end
|
|
|
|
executable_path: READABLE_STRING_8
|
|
|
|
arguments: detachable ARRAYED_LIST [STRING_8]
|
|
|
|
stdin_mode_set: BOOLEAN
|
|
-- Use `stdin' to pass email message, rather than using local file?
|
|
|
|
stdin_termination_sequence: detachable STRING
|
|
-- Termination sequence for the stdin mode
|
|
--| If any, this tells the executable all the data has been provided
|
|
--| For instance, using sendmail, you should have "%N.%N%N"
|
|
|
|
feature -- Status
|
|
|
|
is_available: BOOLEAN
|
|
local
|
|
f: RAW_FILE
|
|
do
|
|
create f.make (executable_path)
|
|
Result := f.exists
|
|
end
|
|
|
|
feature -- Change
|
|
|
|
set_parameters (cmd: like executable_path; args: detachable ITERABLE [READABLE_STRING_8])
|
|
-- Set parameters `executable_path' and associated `arguments'
|
|
local
|
|
l_args: like arguments
|
|
do
|
|
executable_path := cmd
|
|
if args = Void then
|
|
arguments := Void
|
|
else
|
|
create l_args.make (5)
|
|
across
|
|
args as c
|
|
loop
|
|
l_args.force (c.item)
|
|
end
|
|
arguments := l_args
|
|
end
|
|
end
|
|
|
|
set_stdin_mode (b: BOOLEAN; v: like stdin_termination_sequence)
|
|
-- Set the `stdin_mode_set' value
|
|
-- and provide optional termination sequence when stdin mode is selected.
|
|
do
|
|
stdin_mode_set := b
|
|
stdin_termination_sequence := v
|
|
end
|
|
|
|
feature -- Basic operation
|
|
|
|
process_email (a_email: NOTIFICATION_EMAIL)
|
|
local
|
|
l_factory: PROCESS_FACTORY
|
|
args: like arguments
|
|
p: detachable PROCESS
|
|
retried: INTEGER
|
|
do
|
|
if retried = 0 then
|
|
create l_factory
|
|
if stdin_mode_set then
|
|
p := l_factory.process_launcher (executable_path, arguments, Void)
|
|
p.set_hidden (True)
|
|
p.set_separate_console (False)
|
|
|
|
p.redirect_input_to_stream
|
|
p.launch
|
|
if p.launched then
|
|
p.put_string (a_email.message)
|
|
if attached stdin_termination_sequence as v then
|
|
p.put_string (v)
|
|
end
|
|
end
|
|
else
|
|
if attached arguments as l_args then
|
|
args := l_args.twin
|
|
else
|
|
if attached {RAW_FILE} new_temporary_file (generator) as f then
|
|
f.create_read_write
|
|
f.put_string (a_email.message)
|
|
f.close
|
|
create args.make (1)
|
|
args.force (f.name)
|
|
end
|
|
end
|
|
p := l_factory.process_launcher (executable_path, args, Void)
|
|
p.set_hidden (True)
|
|
p.set_separate_console (False)
|
|
|
|
p.launch
|
|
end
|
|
if p.launched and not p.has_exited then
|
|
p.wait_for_exit_with_timeout (1_000_000)
|
|
if not p.has_exited then
|
|
p.terminate
|
|
if not p.has_exited then
|
|
p.wait_for_exit_with_timeout (1_000_000)
|
|
end
|
|
end
|
|
end
|
|
elseif retried = 1 then
|
|
if p /= Void and then p.launched and then not p.has_exited then
|
|
p.terminate
|
|
if not p.has_exited then
|
|
p.wait_for_exit_with_timeout (1_000_000)
|
|
end
|
|
end
|
|
end
|
|
rescue
|
|
retried := retried + 1
|
|
retry
|
|
end
|
|
|
|
feature {NONE} -- Implementation
|
|
|
|
new_temporary_file (a_extension: detachable STRING_8): RAW_FILE
|
|
-- Create file with temporary name.
|
|
-- With concurrent execution, noting ensures that {FILE_NAME}.make_temporary_name is unique
|
|
-- So using `a_extension' may help
|
|
local
|
|
fn: FILE_NAME
|
|
s: like {FILE_NAME}.string
|
|
f: detachable like new_temporary_file
|
|
i: INTEGER
|
|
do
|
|
-- With concurrent execution, nothing ensures that {FILE_NAME}.make_temporary_name is unique
|
|
-- So let's try to find
|
|
from
|
|
until
|
|
f /= Void or i > 1000
|
|
loop
|
|
create fn.make_temporary_name
|
|
s := fn.string
|
|
if i > 0 then
|
|
s.append_character ('-')
|
|
s.append_integer (i)
|
|
create fn.make_from_string (s)
|
|
end
|
|
if a_extension /= Void then
|
|
fn.add_extension (a_extension)
|
|
end
|
|
s := fn.string
|
|
create f.make (fn.string)
|
|
if f.exists then
|
|
i := i + 1
|
|
f := Void
|
|
end
|
|
end
|
|
if f = Void then
|
|
Result := new_temporary_file (Void)
|
|
else
|
|
Result := f
|
|
check not_temporary_file_exists: not Result.exists end
|
|
check temporary_creatable: Result.is_creatable end
|
|
end
|
|
ensure
|
|
not_result_exists: not Result.exists
|
|
result_creatable: Result.is_creatable
|
|
end
|
|
|
|
feature {NONE} -- Environment
|
|
|
|
Execution_environment: EXECUTION_ENVIRONMENT
|
|
once
|
|
create Result
|
|
end
|
|
|
|
invariant
|
|
|
|
end
|