#!/usr/bin/env ruby.ruby3.4

# Copyright 2025 Open Text
#
# ------------------------------------------------------------------------------
# The only warranties for products and services of Open Text and its
# affiliates and licensors (“Open Text”) are as may be set forth in the express
# warranty statements accompanying such products and services.  Nothing herein
# should be construed as constituting an additional warranty. Open Text shall not
# be liable for technical or editorial errors or omissions contained herein. The
# information contained herein is subject to change without notice.
#
# Except as specifically indicated otherwise, this document contains
# confidential information and a valid license is required for possession, use or
# copying. If this work is provided to the U.S. Government, consistent with FAR
# 12.211 and 12.212, Commercial Computer Software, Computer Software
# Documentation, and Technical Data for Commercial Items are licensed to the U.S.
# Government under vendor's standard commercial license.
# ------------------------------------------------------------------------------

# Copyright (C) [2007-2008] Novell, Inc.  All Rights Reserved.

# THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
# IT MAY NOT BE USED, COPIED, DISTRIBUTED, DISCLOSED, ADAPTED, PERFORMED,
# DISPLAYED, COLLECTED, COMPILED, OR LINKED WITHOUT NOVELL'S PRIOR WRITTEN
# CONSENT.  USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD
# SUBJECT THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.

# NOVELL PROVIDES THE WORK "AS IS," WITHOUT ANY EXPRESS OR IMPLIED WARRANTY,
# INCLUDING WITHOUT THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE, AND NON-INFRINGEMENT. NOVELL, THE AUTHORS OF THE WORK,
# AND THE OWNERS OF COPYRIGHT IN THE WORK ARE NOT LIABLE FOR ANY CLAIM, DAMAGES,
# OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE,
# ARISING FROM, OUT OF, OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER
# DEALINGS IN THE WORK.
#require 'net/smtp'
require 'rubygems'
require 'mig'
require 'logger'
=begin
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'migration/migenv'
require 'migration/keystore'
require 'migration/parseargs'
$:.shift
=end

include Migration
def create( options, record  )
	message = ""
	if File.exist?( options['m'] )
		File.open( options['m'], 'r') do |file|
			message = file.readlines.to_s
		end
	else
		raise MigrationException.new("--message-file(-m) '#{options['m']}' does not exist")
	end
	last = record['sn']
	first =record['givenName']
	email = record['mail']
	password = record['userpassword']
	from = options['e']

	#message = "From: #{options['e']}\nSubject: File Access Instructions\n\nHello #{first} #{last},\n" + message + "\nYour new access password is: #{password}" 
	#puts eval('"' + message + '"')
	begin
		str = eval('"' + message + '"')
		return str
	rescue SyntaxError
		raise MigrationException.new("--message-file(-m) #{options['m']} not in correct format")
	end
end

def main
	require 'net/smtp'
	$argdef = [
		['a', 'authentication',
			"the authenticaiton type required by mail server (plain, login, cram_md5)",
			ParseArgText, true ],
		['e', 'email-address',
			"the string that should go in the 'From:' in the e-mail. (eg. admin <admin@mycompany>)",
			ParseArgText, true ],
		[nil, 'mail-server',
			"the SMTP mail server's IP address for posting messages to users",
			ParseArgText, true ],
		['m', 'message-file', 
			"the messages file that will be sent to all migrated users",
			ParseArgText, true ],
		['i', 'verbose',
			"displays verbose information",
			ParseArgBool],
		[nil, "inputfile", "The input file (usually produced by running 'maptrustees').  If not given on the commandline, will read from stdin", ParseArgOrd ],
		[nil, 'precheck', "checks whether system meets all pre-requisite to start mignotify", ParseArgBool],
		[nil, 'debug', "generate debug log", ParseArgBool],
		ParseArgHelp,
		ParseArgUsage
	]

	mignotifyCommand = "#{$0}"
	debugOpt = false
	$*.each do |arg|
		if arg.strip == "--debug"
			debugOpt = true
		end
		mignotifyCommand += " #{arg}"
	end
	initLog(debugOpt, "mignotify")
	print_message(DEBUG, "mignotify command started at #{`date +%d-%m-%y\\ %H:%M:%S`}.")
	print_message(DEBUG, "mignotify command executed as: #{mignotifyCommand}.")
	(options, extraargs) = parseargs(ARGV, $argdef)

        @mailserver = options['mail-server']

	input = nil
	if options['m']
		if not File.exist?( options['m']) or File.size(options['m']) == 0
			print_message(FATAL, "File '#{options['m']}' does not exist or empty.")
			exit 1 
		end	
	end

	if options.has_key?('inputfile')
		unless options['inputfile'].nil? or options['inputfile'].empty?
			if File.exist?( options['inputfile'] ) and File.size(options['inputfile']) != 0
				input = File.open( options['inputfile'], 'r')
			else
				print_message(FATAL, "File '#{options['inputfile']}' does not exist or empty.")
				exit 1 
			end
		end
	else
		input = $stdin
		if input.isatty
			print_message(FATAL, "Must specify input file or provide input to stdin")
			printUsage($argdef)
			exit 1
		end
	end

	key = options['a'].dup
	key.downcase!
	if key.eql?('plain') or key.eql?('login') or key.eql?('cram_md5')
		key = key.to_sym
	else
		raise ArgumentError, "Invalid authentication type: #{key}", caller
		exit 1
	end

	credentials = Migration::KeyStore.credential(options['mail-server'], :email, false, true)
	
       @UserName =   credentials[:username]    
               
	Net::SMTP.start( options['mail-server'], 25, 'localhost.localdomain', credentials[:username], 
				credentials[:password], key) do |smtp|

		YAML.load( input ).each do |record|
			if @opt['precheck']
				$stderr.puts "Information: Validation for mignotify done successfully\n"
				exit 0
			end
			unless record['mail'] == nil
				smtp.send_message( create( options, record ), 
						options['e'], record['mail'] )
				if options['i']
					puts "- emailed: #{record['mail']}"
					puts "  first name: #{record['givenName']}"
					puts "  last name: #{record['sn']}"
				end
			end
		end
	end
	credentials.clear
	
	input.close if input.class == File
	exit 0
end

begin
	main #if __FILE__ == $0
rescue SystemCallError => failed	
	print_message(FATAL, "SystemCallError, #{failed.message}")
	exit failed.errno
rescue Migration::MigrationException => e 
	print_message(FATAL, "MigrationException, " + e.to_s)
	exit Migration::EMIGUNKNOWN[0] 
rescue Migration::MigSyntaxError => e
        print_message(FATAL, "MigSyntaxError, " + e.to_s)
        printUsage($argdef)
        exit e.code
rescue Interrupt
	print_message(DEBUG, "Interrupted by user")
	exit 0
rescue SocketError => e
	print_message(FATAL, "SocketError, " + e.to_s)
	exit Migration::EMIGUNKNOWN[0]
rescue Net::SMTPAuthenticationError => e
	print_message(FATAL, "SMTPAuthenticationError, Failed to authenticate to server #{@mailserver} with username #{@UserName}" + e.to_s)
	exit Migration::EMIGUNKNOWN[0]
rescue
	print_message(FATAL, "Caught exception: #{$!.message}\n Backtrace:\n #{$!.backtrace.join("\n")}")
	exit 1
end
