#!/usr/bin/env python # ========================================================================== # Anguly SendMail 2005 # ======================== # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # =========================================================================== # Report Bug(s) and Exception(s) to # Bug #64626 at http://bugs.gentoo.org # Attachment #61099, Ebuild for Anguly SendMail 2.0.5 __anguly_name__ = ['Anguly SendMail', '2005'] __anguly_pname__ = 'anguly-sendmail' __anguly_release__ = '09 August 2005.' __anguly_version__ = '2.0.9' __anguly_author__ = ['Matteo Bertozzi '] import email import email.Utils import getpass import smtplib import socket import string import sys import os # GLOBAL OBJECTS # Dictionaries = {keys:values} # Mail Headers and None mailheaders = { 'Message-Id':email.Utils.make_msgid(), 'MIME-Version':'1.0', 'X-Priority':'3', 'User-Agent':None, 'Date':email.Utils.formatdate()} smtpinfo = {'server':None, 'username':None, 'passwd':None} mailinfo = {'fmail':None, 'header':None, 'fheaders':None, 'from':None, 'fto':None, 'to':None, 'cc':None, 'fcc':None, 'bcc':None, 'fbcc':None, 'subject':None, 'message':None, 'fmessage':None, 'sign':None, 'fsign':None} # General Options options = {'usereqfrom':0, 'nopasswd':0, 'printheaders':0, 'onlyfmail':0, 'noagent':0, 'onlyfheaders':0, 'loop':None, 'scc':0, 'savesent':0, 'debug':0} # Colors Code ccode = {'default':'\x1b[0m', 'blue':'\x1b[34;01m', 'white':'\x1b[01m', 'lblue':'\x1b[01;36m', 'yellow':'\x1b[33;01m', 'green':'\x1b[32;01m', 'red': '\x1b[31;01m'} try: ANGULY_DIR = os.environ['HOME'] + "/.anguly/" except KeyError: ANGULY_DIR = "." ANGULY_DIR_SENT = "/sent/" ANGULY_STOP_MSG = "Anguly Stopped." # ========== USER-AGENT: try import from os 'uname' ================= mailheaders['User-Agent'] = "Anguly/" + __anguly_version__ + " (" try: from os import uname sysinfo = uname()[0] + ' ' + uname()[2] + ", " except ImportError: sysinfo = "" mailheaders['User-Agent'] += sysinfo + __anguly_release__[:len(__anguly_release__)-1] + ")" DEFAULT_USERAGENT = mailheaders['User-Agent'] # ========== USER-AGENT: End of Try import os.uname ================== ###### GET SHELL Number of COLS ################################# #try: # from os import popen # fd = popen('stty size', 'r') # _ncols = string.atoi(fd.read().split()[1]) # fd.close() # shellcols = ' ' # _ncols = range(_ncols-7) # print _ncols # for i in _ncols: shellcols += ' ' #except: # shellcols = ' ' ###### GET SHELL COLS: End ###################################### # ============== Color Print ===================================== def ctext (text, color='default', newline=1): print ccode[color] + text + ccode['default'], for i in range(newline): print # ================== All Color = '', No Color =================== def set_nocolor (): global ccode for color in ccode.keys(): ccode[color] = '' # ============= Print [ OK ] of [ !! ] if there is an error ========== def logo_stat (num, string=None): print "[", if (num == 1): ctext("!!", 'red', 0) else: ctext("OK", 'green', 0) print "]" if (string != None): perror(string) # ======== Print Error Message, If (esc == 1) exit from prog ============ def perror (string, esc=1): ctext("\r\n *", 'red', 0) print string if (esc == 1): print # New Line at the end of the prog sys.exit(1) # ===================== Get String ===================================== def getstring(info): try: return(raw_input(info).strip()) except KeyboardInterrupt: perror(ANGULY_STOP_MSG) except EOFError: perror(ANGULY_STOP_MSG) # ===================== Get Password =================================== def getpasswd(info): try: return(getpass.getpass(info)) except KeyboardInterrupt: perror(ANGULY_STOP_MSG) except EOFError: perror(ANGULY_STOP_MSG) # ================ Convert string in num return 1 by default ============ def myAtoi(str): try: return(str.atoi()) except: return(1) # =============================== Options argv --file =============================== def chkopts(short, long, str): pos = long.find('=') if (pos != -1): if (str[:short.find('=')+1] == short or str[:pos+1] == long): return(1) else: if (str == short or str == long): return(1) return(0) # ===================================== Value argv --file="text" ================ def getoptsprm(short, long, str): if (chkopts(short, long, str)): return(str[(str.index('=')+1):]) return(None) # =================== Get Anguly Options ============================================ def getargv(argv): global DEFAULT_USERAGENT global mailheaders global smtpinfo global mailinfo global options for opt in argv: if (opt == argv[0]): continue elif (chkopts("-h", "--help", opt)): anguly_help(), sys.exit(0) elif (chkopts("-v", "--version", opt)): anguly_version(), sys.exit(0) elif (chkopts("-d", "--debug", opt)): options['debug'] = 1 elif (chkopts("-nc", "--no-color", opt)): set_nocolor() # elif (chkopts("-dp", "--no-print", opt)): print >> ?? elif (chkopts("-uef", "--user-equal-from", opt)): options['usereqfrom'] = 1 elif (chkopts("-np", "--no-passwd", opt)): options['nopasswd'] = 1 elif (chkopts("-ph", "--print-headers", opt)): options['printheaders'] = 1 elif (chkopts("-sm", "--save-sent", opt)): options['savesent'] = 1 elif (chkopts("-ofm", "--only-fmail", opt)): options['onlyfmail'] = 1 elif (chkopts("-na", "--no-agent", opt)): options['noagent'] = 1 elif (chkopts("-ofh", "--only-fheaders", opt)): options['onlyfheaders'] = 1 elif (chkopts("-scc", "--show-cc", opt)): options['scc'] = 1 if (mailinfo['from'] == None): mailinfo['from'] = getoptsprm("-from=", "--from=", opt); if (mailinfo['to'] == None): mailinfo['to'] = getoptsprm("-to=", "--to=", opt); if (mailinfo['fto'] == None): mailinfo['fto'] = getoptsprm("-fto=", "--fto=", opt); if (mailinfo['cc'] == None): mailinfo['cc'] = getoptsprm("-cc=", "--cc=", opt); if (mailinfo['fcc'] == None): mailinfo['fcc'] = getoptsprm("-fcc=", "--fcc=", opt) if (mailinfo['bcc'] == None): mailinfo['bcc'] = getoptsprm("-bcc=", "--bcc=", opt) if (mailinfo['fbcc'] == None): mailinfo['fbcc'] = getoptsprm("-fbcc=", "--fbcc=", opt) if (mailinfo['subject'] == None): mailinfo['subject'] = getoptsprm("-subj=", "--subject=", opt) if (mailinfo['message'] == None): mailinfo['message'] = getoptsprm("-msg=", "--message=", opt) if (mailinfo['fmessage'] == None): mailinfo['fmessage'] = getoptsprm("-fmsg=", "--fmessage=", opt) if (mailinfo['sign'] == None): mailinfo['sign'] = getoptsprm("-sign=", "--sign=", opt) if (mailinfo['fsign'] == None): mailinfo['fsign'] = getoptsprm("-fsign=", "--fsign=", opt) if (smtpinfo['server'] == None): smtpinfo['server'] = getoptsprm("-smtp=", "--smtp=", opt) if (smtpinfo['username'] == None): smtpinfo['username'] = getoptsprm("-user=", "--username=", opt) if (smtpinfo['passwd'] == None): smtpinfo['passwd'] = getoptsprm("-passwd=", "--passwd=", opt) if (mailinfo['fmail'] == None): mailinfo['fmail'] = getoptsprm("-fmail=", "--fmail=", opt) if (mailinfo['header'] == None): mailinfo['header'] = getoptsprm("-ahead=", "--header=", opt) if (mailinfo['fheaders'] == None): mailinfo['fheaders'] = getoptsprm("-fheaders=", "--fheaders=", opt) if (mailheaders['Message-Id'] == None): mailheaders['Message-Id'] = getoptsprm("-message-id=", "--message-id=", opt) if (mailheaders['MIME-Version'] == None): mailheaders['MIME-Version'] = getoptsprm("-mime-version=", "--mime-version=", opt) if (mailheaders['Date'] == None): mailheaders['Date'] = getoptsprm("-date=", "--date=", opt) if (mailheaders['X-Priority'] == None): mailheaders['X-Priority'] = getoptsprm("-priority=", "--priority=", opt) if (options['loop'] == None): options['loop'] = getoptsprm("-loop", "--loop=", opt) if (mailheaders['User-Agent'] == DEFAULT_USERAGENT): mailheaders['User-Agent'] = getoptsprm("-user-agent=", "--user-agent=", opt) if (mailheaders['User-Agent'] == None): mailheaders['User-Agent'] = DEFAULT_USERAGENT if (smtpinfo['username'] == None and options['usereqfrom'] == 1): smtpinfo['username'] = mailinfo['from'] # ===================== Show Anguly Version and Details ====================================== def anguly_version(): global mailheaders ctext(string.join(__anguly_name__, ' ') + ' -', 'white', 0) print __anguly_version__ ctext("Release Date:", 'white', 0) print __anguly_release__ if (options['noagent'] == 0 and mailheaders['User-Agent'] != None): ctext("User-Agent:", 'white', 0) print mailheaders['User-Agent'] ctext("Author:", 'white', 0) print string.join(__anguly_author__, ',') print ctext("*", 'yellow', 0) print "Report Bug(s) and Exception(s) to " print # ================== Show Anguly Help ==================================================== def anguly_help(): ctext(string.join(__anguly_name__, ' ') + ' - ' + __anguly_version__, 'white') print ctext("Usage:", 'white') print " " + __anguly_pname__ print " " + __anguly_pname__ + " [ options ] " print " " + __anguly_pname__ + " [ options ] [ --version ]" print " " + __anguly_pname__ + " [ options ] [ --no-color ]" print " " + __anguly_pname__ + " [ options ] [ --print-headers ]" print print ctext("Options:", 'white') print " -h --help Help. This Screen." print " -v --version " + __anguly_name__[0] + " version." print print " -d --debug Verbose Output (SMTP Debug)" print " -nc --no-color Print without color." # print " -dp --no-print Don't Print Any Messages." print print " -uef --user-equal-from SMTP user = From." print " -np --no-passwd No SMTP Login." print " -ph --print-headers Print Only Message Headers (NO SEND)." print " -sm --save-sent Save Sent Mail in ~/.anguly/sender/sent." print print " -ofm --only-fmail Headers and Message from -fmail." print " --fmail='filename' Get Headers and Message from File." print ctext('Mail Header Options:', 'white') print " -na --no-agent Send Mail without User-Agent." print " -ofh --only-fheaders Use Only headers on file --fheaders" print print " --header='string' Add header to mail headers. " + ccode['yellow'] + "*" + ccode['default'] print " --fheaders='filename' Get Headers from File. " + ccode['yellow'] + "*" + ccode['default'] print " --message-id='string' Message-Id: string" print " --mime-version='version' MIME-Version: version (Default is '1.0')" print " --user-agent='string' User-Agent: string" print " --date='string' Date: string" print " --priority='N' X-Priority: N (Default is '3')" print ctext("SMTP Options:", 'white') print " --smtp='string' SMTP Server." print " --username='string' SMTP Username. If None 'username = from'." print " --passwd='string' SMTP Password." print ctext("Mail Options:", 'white') print " -scc --show-cc Show CC and BCC input text." print print " --from='string' Mail Sender. 'From: Pippo '" print " --fto='filename' Get Mail Recevers from File." print " --to='string1 string2' Mail Recevers 'To: pippo@disney.net'" print " --fcc='filename' Get Mail Copy Recevers from File." print " --cc='string1 string2' Mail Copy Recevers 'Cc: pippo@disney.net'" print " --fbcc='filename' Get Mail B. Copy Recevers from File." print " --bcc='string1 string2' Mail B. Copy Recevers 'Bcc: pippo@disney.net'" print print " --subject='string' Mail Subject 'Subject: string'" print " --message='string' Message string. " print " --fmessage='filename' Get Message From 'filename'." print " --sign='string' Append Sign." print " --fsign='filename' Append Sign, readed from file." print print " --loop='N' Send N mail(s) to recevers." print ctext("Notes:", 'white') ctext(" *", 'yellow', 0) print "Default Headers are:" # ========== Print Default Headers ========== i = 0 for header in mailheaders.keys(): if (i == 0): print " ", print "'" + ccode['lblue'] + header + ccode['default'] + "'", i += 1 if (i == 5): i = 0 print if (i != 5): print # ========== END Print Default Headers ========== print "Report Bug(s) and Exception(s) to " print # ========== Get File, return file as string ================================================== def getfile(filename, lseparator='\r\n', delblankline=1): if (filename == None): perror("No Input File.") try: file = "" fd = open(filename, 'r') while (1): line = fd.readline() if (line == ''): break line = line.strip() if (line != ''): file += line + lseparator elif (delblankline == 0): file += line + lseparator fd.close() return(file) except IOError, msgerror: perror(msgerror) except KeyboardInterrupt: perror(ANGULY_STOP_MSG) except EOFError: perror(ANGULY_STOP_MSG) # ===================== Print Mail Headers =================================================== def print_mail(mail): print ctext("E-Mail Headers:", 'white') print mail sys.exit(0) # ====================== Request Login Informations ============================================= def smtp_logininfo(): global smtpinfo global options if (smtpinfo['server'] == None or smtpinfo['username'] == None or (options['nopasswd'] == 0 and smtpinfo['passwd'] == None)): ctext("\t\t\tSMTP Info", 'green') # SMTP Server if (smtpinfo['server'] == None): smtpinfo['server'] = getstring(ccode['lblue'] + "SMTP Server: " + ccode['default']) else: ctext("SMTP Server:", 'lblue') print smtpinfo['server'] # Username if (smtpinfo['username'] == None and options['usereqfrom'] == 0): smtpinfo['username'] = getstring(ccode['lblue'] + "SMTP Username: " + ccode['default']) else: ctext("SMTP Username:", 'lblue', 0) print smtpinfo['username'] # Passwd if (smtpinfo['passwd'] == None and options['nopasswd'] == 0): smtpinfo['passwd'] = getpasswd(ccode['lblue'] + "SMTP Passwd: " + ccode['default']) print # ============= Get From, To, CC, Bcc, Subject of the mail ========================================= def get_mailinfo(): global smtpinfo global mailinfo # From: if (mailinfo['from'] != None): ctext("From:", 'lblue', 0) if (options['usereqfrom'] == 1): if (mailinfo['from'] == None): mailinfo['from'] = smtpinfo['username'] else: smtpinfo['username'] = mailinfo['from'] print mailinfo['from'] else: mailinfo['from'] = getstring(ccode['lblue'] + "From: " + ccode['default']) # To: if (mailinfo['fto'] == None): if (mailinfo['to'] == None): print " To Send Mail at more then one:" print " Example. To: pers1@host.it pers2@host.it pers3@host.it ecc..." mailinfo['to'] = getstring(ccode['lblue'] + "To: " + ccode['default']).split() else: mailinfo['to'] = mailinfo['to'].split() ctext("To:", 'lblue', 0) print mailinfo['to'] else: mailinfo['to'] = getfile(mailinfo['fto'], ' ').split() ctext("To:", 'lblue', 0) print mailinfo['to'] if (options['scc'] == 1): # CC: if (mailinfo['fcc'] == None): if (mailinfo['cc'] == None): print " Leave Blank Cc or Bcc if you don't use it (press only enter)." mailinfo['cc'] = getstring(ccode['lblue'] + "Cc: " + ccode['default']).split() else: mailinfo['cc'] = mailinfo['cc'].split() else: mailinfo['cc'] = getfile(mailinfo['fcc'], ' ').split() # BCC: if (mailinfo['fbcc'] == None): if (mailinfo['bcc'] == None): mailinfo['bcc'] = getstring(ccode['lblue'] + "Bcc: " + ccode['default']).split() else: mailinfo['bcc'] = mailinfo['bcc'].split() else: mailinfo['bcc'] = getfile(mailinfo['fbcc'], ' ').split() # Subject: if (mailinfo['subject'] == None): mailinfo['subject'] = getstring(ccode['lblue'] + "Subject: " + ccode['default']) print # ======================= Get Text of the Mail ===================================== def get_mailmessage(): global mailinfo if (mailinfo['message'] == None and mailinfo['fmessage'] == None): mailinfo['message'] = "" ctext("Enter message, end with ^D (ctrl + d):", 'lblue') while (1): try: line = raw_input("") except EOFError: break except KeyboardInterrupt: perror(ANGULY_STOP_MSG) mailinfo['message'] += line + smtplib.CRLF elif (mailinfo['fmessage'] != None): mailinfo['message'] = getfile(mailinfo['fmessage'], smtplib.CRLF, 0) print mailinfo['message'] print # =============== Make Mail, headers + message ==================================== def make_mail(): global mailheaders mail = "" # HEADERS if (options['onlyfheaders'] == 0): for header in mailheaders.keys(): if (options['noagent'] == 1 and header == "User-Agent"): continue mail += header + ": " + mailheaders[header] + smtplib.CRLF if (mailinfo['header'] != None): mail += mailinfo['header'] + smtplib.CRLF elif (mailinfo['fheaders'] != None): mail += getfile(mailinfo['fheaders'], smtplib.CRLF) + smtplib.CRLF # MAIL INFO mail += "From: " + mailinfo['from'] + smtplib.CRLF if (mailinfo['to'] != None): mail += "To: " + ", ".join(mailinfo['to']) + smtplib.CRLF if (mailinfo['cc'] != None): mail += "Cc: " + ", ".join(mailinfo['cc']) + smtplib.CRLF if (mailinfo['bcc'] != None): mail += "Bcc: " + ", ".join(mailinfo['bcc']) + smtplib.CRLF mail += "Subject: " + mailinfo['subject'] + smtplib.CRLF else: mail += getfile(mailinfo['fheaders'], smtplib.CRLF) + smtplib.CRLF mail += smtplib.CRLF # MESSAGE AND SIGN mail += mailinfo['message'] + smtplib.CRLF if (mailinfo['sign'] != None): mail += "---" + smtplib.CRLF + mailinfo['sign'] + smtplib.CRLF elif (mailinfo['fsign'] != None): mail += "---" + smtplib.CRLF + getfile(mailinfo['sign'], smtplib.CRLF, 0) + smtplib.CRLF return(mail) # ============ Connect with SMTP ==================================================== def smtp_connect(): try: ctext(" *", 'yellow', 0) print "Connecting to '" + smtpinfo['server'] + "'...", sock = smtplib.SMTP(smtpinfo['server']) if (options['debug'] == 1): sock.set_debuglevel(1) logo_stat(0) except smtplib.SMTPConnectError, msgerror: logo_stat(1, msgerror) except socket.gaierror, msgerror: logo_stat(1, msgerror) except socket.error, msgerror: logo_stat(1, msgerror) except KeyboardInterrupt: logo_stat(1, ANGULY_STOP_MSG) except EOFError: logo_stat(1, ANGULY_STOP_MSG) # sock.helo('localhost') # implicitly called by the sendmail() when necessary. # LOGIN if (options['nopasswd'] == 0): ctext(" *", 'yellow', 0) print "Login for '" + smtpinfo['username'] + "'...", try: sock.login(smtpinfo['username'], smtpinfo['passwd']) logo_stat(0) except smtplib.SMTPHeloError, msgerror: logo_stat(1, msgerror) except smtplib.SMTPAuthenticationError, msgerror: logo_stat(1, msgerror) except smtplib.SMTPException, msgerror: logo_stat(1, msgerror) except AttributeError, msgerror: logo_stat(1, msgerror) except KeyboardInterrupt: logo_stat(1, ANGULY_STOP_MSG) except EOFError: logo_stat(1, ANGULY_STOP_MSG) return(sock) # ================== Send Mail ===================================================== def smtp_sendmail(sock, mail): global options if (options['loop'] == None): options['loop'] = '1' mailnum = range(myAtoi(options['loop'])) if (mailinfo['to'] == None): mailinfo['to'] = [] if (mailinfo['cc'] == None): mailinfo['cc'] = [] if (mailinfo['bcc'] == None): mailinfo['bcc'] = [] for i in mailnum: print " (" + str(i + 1) + ")", ctext("Sending Message... ", 'green', 0) try: sock.sendmail(mailinfo['from'], mailinfo['to'] + mailinfo['cc'] + mailinfo['bcc'], mail) logo_stat(0) except smtplib.SMTPHeloError, msgerror: logo_stat(1, msgerror) except smtplib.SMTPRecipientsRefused, msgerror: logo_stat(1, msgerror) except smtplib.SMTPSenderRefused, msgerror: logo_stat(1, msgerror) except smtplib.SMTPDataError, msgerror: logo_stat(1, msgerror) except smtplib.SMTPConnectError, msgerror: logo_stat(1, msgerror) except KeyboardInterrupt: logo_stat(1, ANGULY_STOP_MSG) except EOFError: logo_stat(1, ANGULY_STOP_MSG) try: sock.quit() except KeyboardInterrupt: logo_stat(1, ANGULY_STOP_MSG) except EOFError: perror(ANGULY_STOP_MSG) # ============ Save Sent Mail ======================================================= def save_sent(mail, sender): os.mkdir(ANGULY_DIR) os.mkdir(ANGULY_DIR + sender ) os.mkdir(ANGULY_DIR + sender + ANGULY_DIR_SENT) try: fd = open(ANGULY_DIR + sender + ANGULY_DIR_SENT + "counter.db") sentcounter = fd.read() fd.close() except IOError: sentcounter = '0' sentcounter = myAtoi(sentcounter) + 1 fd = open(ANGULY_DIR + sender + ANGULY_DIR_SENT + str(sentcounter), 'w') fd.write(mail) fd.close() ctext("Message Saved as: ", 'green', 0) print ANGULY_DIR + sender + ANGULY_DIR_SENT + str(sentcounter) # =========== Anguly Main Function (Start Prog) ===================================== def main(): ctext(string.join(__anguly_name__,' ') + ' - ' + __anguly_version__, 'white', 2) smtp_logininfo() if (options['onlyfmail'] == 1): if (mailinfo['fmail'] == None): mailinfo['fmail'] = getstring(ccode['lblue'] + "Mail File: " + ccode['default']) mail = getfile(mailinfo['fmail'], smtplib.CRLF, 0) msg = email.message_from_string(mail) mailinfo['from'] = msg['From'] mailinfo['to'] = msg['To'] if (options['printheaders'] == 1): print_mail(mail) else: if (options['onlyfheaders'] == 0): get_mailinfo() get_mailmessage() mail = make_mail() if (options['printheaders'] == 1): print_mail(mail) sock = smtp_connect() smtp_sendmail(sock, mail) if (options['savesent'] == 1): save_sent(mail, smtpinfo['username']) print # ==================================================================== if (__name__ == '__main__'): try: if (len(sys.argv) > 1): getargv(sys.argv) main() sys.exit(0) except KeyboardInterrupt: perror(ANGULY_STOP_MSG) except EOFError: perror(ANGULY_STOP_MSG) sys.exit(0)