#!/usr/bin/python # # Usage: faxnotify log-file image-file [image-file ...] # # This script converts received fax TIFF files to a PDF # file and delivers them according to the fax preferences. # import os, sys, string import shutil, errno, socket from email import Encoders from email.Message import Message from email.MIMEBase import MIMEBase from email.MIMEMultipart import MIMEMultipart def defaults_read(key, domain = '/Library/Preferences/com.apple.print.FaxPrefs'): """Read the value of 'key' from the defaults system""" i,o,e = os.popen3('/usr/bin/defaults read ' + domain + ' ' + key) i.close() value = string.rstrip(o.read()) o.close() e.close() return value def quote(x): """Add quotes to a shell command argument string""" if '\'' not in x : return '\'' + x + '\'' s = '"' for c in x: if c in '\\$"`': s = s + '\\' s = s + c s = s + '"' return s def remote_id(): """Find the sender's phone number so it can be used in the PDF name""" try: remote_id = os.environ['REMID'] except: remote_id = '?' if remote_id == '?' : remote_id = 'Unknown' return remote_id def copy_versioned_file(srcfile, dstdir): """Copy a file to a directory adding versioning as needed""" fsrc = None fdst = None if not os.path.isdir(dstdir) : print >> sys.stderr, 'faxnotify: Save to directory missing ' + quote(dstdir.encode('unicode-escape')) return -1 old_uid = os.getuid() old_mask = os.umask(002) try: # open src as root fsrc = open(srcfile, 'rb') # get the owner of the destination directory dstdir_owner = os.lstat(dstdir).st_uid # step down to the dir owner's uid before creating the file os.seteuid(dstdir_owner) # create the full path for the destination file and seperate # the components in case we have to version it dstfile = dstdir + '/' + os.path.split(srcfile)[1] name, ext = os.path.splitext(dstfile) for i in xrange(1, 10000): try: fd = os.open(dstfile, os.O_WRONLY | os.O_CREAT | os.O_EXCL) fdst = os.fdopen(fd, 'wb') break except (OSError, IOError), e: if e.errno != errno.EEXIST: raise # file exists, find next available version dstfile = '%s %d%s' % (name, i, ext) # we've created a new unique file, now copy the contents of src into it shutil.copyfileobj(fsrc, fdst) except (OSError, IOError), e: print >> sys.stderr, 'faxnotify: Save to failed;' , e except: print >> sys.stderr, 'faxnotify: Save to ' + quote(dstdir.encode('unicode-escape')) + ' failed' pass if fsrc: fsrc.close() if fdst: fdst.close() os.umask(old_mask) os.seteuid(old_uid) return 0 def email_fax(receipents, sender, pdffile): """Send email to the receipents with an attached file""" msg = MIMEMultipart() msg['Subject'] = pdffile msg['To'] = receipents msg['From'] = sender msg.preamble = 'You will not see this in a MIME-aware mail reader.\n' # To guarantee the message ends with a newline msg.epilogue = '' fp = open(pdffile) pdf = MIMEBase('application', 'pdf') pdf.set_payload(fp.read()) fp.close() # Encode the payload using Base64 Encoders.encode_base64(pdf) # Set the filename parameter pdf.add_header('Content-Disposition', 'attachment', filename=pdffile) msg.attach(pdf) stdout, stdin = os.popen2('/usr/sbin/sendmail -oi -t -r' + quote(sender)) stdout.write(msg.as_string()) stdout.close() stdin.close() # # Make sure we have enough arguments # if len(sys.argv) == 1 : print >> sys.stderr, 'Usage: faxnotify log-file image-file [image-file ...]' sys.exit(2) # If there are no tiff files to process just exit quietly. if len(sys.argv) == 2 : sys.exit(0) tiff_files = string.join(map(quote, sys.argv[2:])) pdf_file = 'FAX from ' + remote_id() + '.pdf' try: # Convert TIFFs into a single PDF command = '/usr/libexec/fax/imagestopdf ' + tiff_files + ' ' + quote(pdf_file) if os.system(command) : print >> sys.stderr, 'faxnotify: ' + command + ' failed' sys.exit(1) # Print on printer if defaults_read('PrintFax') == '1' : printer = quote(defaults_read('PrinterID')) faxuser = defaults_read('FaxUser') if faxuser == '' : faxuser = 'FaxNotify' faxuser = quote(faxuser) command = '/usr/bin/lpr -P ' + printer + ' -U ' + faxuser + ' ' + quote(pdf_file) if os.system(command) : print >> sys.stderr, 'faxnotify: Print on printer ' + printer + ' failed' # Save to if defaults_read('SaveFax') == '1' : copy_versioned_file(pdf_file, unicode(defaults_read('SavePath'), 'unicode-escape')) # Email to if defaults_read('EmailFax') == '1' : recipients = defaults_read('EmailRecipient') sender = defaults_read('EmailSender') if sender == '' : if socket.gethostname()[-7:] == '.local.' : sender = recipients.split(',')[0].strip(whitespace + '<>') else : sender = 'FaxNotify' email_fax(recipients, sender, pdf_file) finally: # Remove the TIFFs and converted PDF map(os.remove, sys.argv[2:]) if os.path.exists(pdf_file): os.remove(pdf_file)