Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
MailViaServer3/MailViaServer3
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
executable file
220 lines (178 sloc)
6.54 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
from __future__ import print_function | |
#----------------------------------------------------------------------- | |
# Imports | |
#----------------------------------------------------------------------- | |
import os, sys, time, getopt, getpass, smtplib | |
#----------------------------------------------------------------------- | |
# Constants | |
#----------------------------------------------------------------------- | |
PORT_STARTTLS = 587 | |
#----------------------------------------------------------------------- | |
# Functions | |
#----------------------------------------------------------------------- | |
def Usage(msg=None): | |
print (""" | |
MailViaServer3 [-h HELO_HOST ] [-f MAIL_FROM] -F<findstr> -R<replacestr> -s <server> {<msg-file>|-} <addr> [<addr> ...] | |
Mails [file] (or standard in) to mail address <addr> | |
through the mail server given by -s <server>, or writes | |
email to standard out. | |
Options: | |
-h HELO Name of host passed in SMTP HELO command. | |
Default is "%s". | |
-f FROM Return addressed passwd in SMTP MAIL FROM command. | |
Default is "%s". | |
-A FILE Read addresses from FILE. One address per line, | |
blank lines and comments (#) are ignored. | |
-F FINDSTR Find FINDSTR in <msg-file> and repace with REPSTR below. | |
Both -F and -R can be repeated multiple times. | |
-R REPSTR See -F above | |
-s SERVER Send email via mail server SERVER. If none given, | |
email is formatted and sent to standard out. | |
This is useful for testing. | |
-t FILE Use StartTLS on port %s. Will read server host name, | |
email account name, and password, from first, second and | |
third line. | |
-T Use StartTLS on port %s. Will prompt user for account | |
and password. | |
-v Display progress | |
Example: | |
This reads an email template from standard input. It uses | |
the -F and -R options to substitute the value of {NAME} in | |
the template, and addresses the email to b.jones@example.com. | |
The email is sent to the email server smtp.myplace.edu. | |
The FROM address submitted to the email server is smith@myplace.edu. | |
Note that this FROM address is not the same as the From: address | |
used inside the email template. | |
MailViaServer3 -f smith@myplace.edu -s smtp.myplace.edu -F{NAME} -RJohnboy - b.jones@example.com <<EOM | |
> Subject: This is a test message. | |
> From: Another.place@another.time.com | |
> | |
> Hi there {NAME} | |
> EOM | |
""" % (DEF_HELO, DEF_FROM, PORT_STARTTLS, PORT_STARTTLS)) | |
raise SystemExit | |
def print_error(msg): | |
print() | |
print(" ERROR: ", msg) | |
print() | |
sys.exit() | |
def get_addr_from_file(filename): | |
return [line for line in [line.strip() for line in open(filename).readlines()] if line and line[0]!='#'] | |
def process_opts(opts): | |
newopts = {} | |
findstr = [] | |
repstr = [] | |
for k,v in opts: | |
if k=='-F': | |
findstr.append(v) | |
elif k=='-R': | |
repstr.append(v) | |
else: | |
newopts[k] = v | |
return newopts, findstr, repstr | |
# Read email user name and password from console | |
def get_user_pass(): | |
user = input("Enter email account name: ") | |
passwd = getpass.getpass("Enter email account password: ") | |
return user, passwd | |
# Read email user name and password from plain text file | |
def read_server_user_pass_file(fname): | |
server_name, user, passwd = '', '', '' | |
with open(fname) as fin: | |
server_name = fin.readline().strip() | |
user = fin.readline().strip() | |
passwd = fin.readline().strip() | |
return server_name, user, passwd | |
def write_verbose(msg): | |
if VERBOSE: | |
print("VERBOSE: ", time.strftime("%Y-%m-%d %H:%M:%D"), msg) | |
#----------------------------------------------------------------------- | |
# Initialize Global Variables | |
#----------------------------------------------------------------------- | |
# Default envelope from address: MAIL FROM: | |
user = os.environ.get("USER","localuser") | |
host = os.environ.get("HOSTNAME","localhost") | |
DEF_FROM = user + "@" + host | |
DEF_HELO = host | |
VERBOSE = False | |
#----------------------------------------------------------------------- | |
# Main | |
#----------------------------------------------------------------------- | |
def main(): | |
global VERBOSE | |
# Get options | |
opts, args = getopt.getopt(sys.argv[1:], "f:h:s:A:F:R:Tvt:"); | |
opts, findstr, repstr = process_opts(opts) | |
helo = opts.get('-h', DEF_HELO) | |
from_address = opts.get('-f', DEF_FROM) | |
addr_file = opts.get('-A', None) | |
server_name = opts.get('-s', None) | |
VERBOSE = '-v' in opts | |
# Make sure number of findstr[] and repstr[] match | |
if not len(findstr)==len(repstr): | |
print_error("Number of find strings and replace strings don't match.") | |
# Get servername and msg-file from command-line | |
try: | |
filename = args.pop(0) | |
except: | |
Usage() | |
# Get addresses from option or command-line | |
if addr_file: | |
to_addresses = get_addr_from_file(addr_file) | |
else: | |
# If to_addresses not on command-line, show Usage | |
try: | |
to_addresses = args | |
except: | |
Usage() | |
# Read mail message | |
if filename=="-": | |
fin = sys.stdin | |
msg = fin.read() | |
else: | |
fin = open(filename,"r") | |
msg = fin.read() | |
fin.close() | |
# Make sure all the find strings are in the message | |
for s in findstr: | |
if msg.find(s)==-1: | |
print_error('Cannot find the findstr "%s" in mail file' % s) | |
sys.exit() | |
# Replace string placeholders in message | |
for i in range(len(findstr)): | |
msg = msg.replace(findstr[i], repstr[i]) | |
# Send message | |
if server_name or '-t' in opts: | |
# Use STARTTLS | |
if '-T' in opts or '-t' in opts: | |
# Get username and password | |
if '-T' in opts: | |
username, password = get_user_pass() | |
else: | |
config_server_name, username, password = read_server_user_pass_file(opts['-t']) | |
# Let user override configured server name with name from the command line | |
if server_name==None: server_name = config_server_name | |
write_verbose("STARTTLS: open server connection") | |
sm = smtplib.SMTP(server_name, PORT_STARTTLS) | |
write_verbose("STARTTLS: starttls") | |
sm.starttls() | |
write_verbose("STARTTLS: login") | |
sm.login(username, password) | |
write_verbose("STARTTLS: ehlo") | |
sm.ehlo(helo) | |
write_verbose("STARTTLS: sendmail") | |
sm.sendmail(from_address, to_addresses, msg) | |
write_verbose("STARTTLS: finished") | |
# Use standard SMTP (port 25) | |
else: | |
write_verbose("SMTP: open server connection") | |
sm = smtplib.SMTP(server_name) | |
write_verbose("SMTP: helo") | |
sm.helo(helo) | |
write_verbose("SMTP: sendmail") | |
sm.sendmail(from_address, to_addresses, msg) | |
write_verbose("SMTP: finished") | |
else: | |
print(msg) | |
main() |