#!/usr/bin/env python
#
# (c) Copyright 2003-2005 Hewlett-Packard Development Company, L.P.
#
# 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 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
#
# Author: Don Welch
#

_VERSION = '0.7'

import sys
import getopt
import ConfigParser
import os.path, os
import socket
import syslog

config_file = '/etc/hp/hplip.conf'
home_dir = ''

if os.path.exists(config_file):
    config = ConfigParser.ConfigParser()
    config.read(config_file)

    try:
        home_dir = config.get('dirs', 'home')
    except:
        syslog.syslog(syslog.LOG_CRIT, "hpfax: Error setting home directory: home= under [dirs] not found.")
        sys.exit(1)
else:
    syslog.syslog(syslog.LOG_CRIT, "hpfax: Error setting home directory: /etc/hp/hplip.conf not found.")
    sys.exit(1)

if not home_dir or not os.path.exists(home_dir):
    syslog.syslog(syslog.LOG_CRIT, "hpfax: Error setting home directory: home directory %s not found." % home_dir)
    sys.exit(1)

sys.path.insert( 0, home_dir )

try:
    from base.g import *
    from base.codes import *
    from base import device, utils, service
except ImportError:
    syslog.syslog(syslog.LOG_CRIT, "Error importing HPLIP modules.")
    sys.exit(-1)

def usage():
    utils.log_title('CUPS Fax Backend (hpfax:)', _VERSION)
    sys.exit(0)

try:
    opts, args = getopt.getopt(sys.argv[1:], 'l:h', ['level=', 'help'])

except getopt.GetoptError:
    usage()

for o, a in opts:

    if o in ('-l', '--logging'):
        log_level = a.lower().strip()
        log.set_level(log_level)

    elif o in ('-h', '--help'):
        usage()

log.set_module("hpfax")

if len( args ) == 0:
    try:
        devices = device.probeDevices(sock=None, bus='usb,par', timeout=5,
                                      ttl=4, filter='fax', format='cups')
    except Error:
        log.error("Unable to contact HPLIP I/O (hpssd).")
        sys.exit(1)

    if len(devices):
        for d in devices:
            print d.replace('hp:/', 'hpfax:/')
    else:
        print 'direct hpfax:/no_device_found "Unknown" "hpfax no_device_found"'
        
    sys.exit(0)

else:
    # CUPS provided environment
    try:
        device_uri = os.environ['DEVICE_URI']
        printer_name = os.environ['PRINTER']
    except KeyError:
        log.error("Improper environment: Must be run by CUPS.")
        sys.exit(1)
        
    log.debug(args)
    
    try:
        job_id, username, title, copies, options = args[0:5]
    except IndexError:
        log.error("Invalid command line: Invalid arguments.")
        sys.exit(1)
        
    try:
        input_fd = file(args[5], 'r')
    except IndexError:
        input_fd = 0
        
    log.stderr("hpfax: URI=%s, Printer=%s, Job ID=%s, User=%s, Title=%s, Copies=%s, Options=%s" % \
        (device_uri, printer_name, job_id, username, title, copies, options))

    pdb = pwd.getpwnam(username)
    home_folder, uid, gid = pdb[5], pdb[2], pdb[3]
    
    log.stderr("hpfax: User home=%s, Uid=%d, Gid=%d" % (home_folder, uid, gid))
    
    output_dir = [(home_folder, 0177), ('/tmp', 0133), ('/var/tmp', 0133), ('/usr/tmp', 0133)]
    for d, u in output_dir:
        output_filename = os.path.join(d, 'hpfax-%s.g3' % job_id)
        os.umask(u)
        try:
            output_file = file(output_filename, 'w')
        except IOError:
            continue
        else:
            break
    else:
        log.error("Could not find a suitable location to write the output file!") 
        sys.exit(1)
    
    log.stderr("hpfax: Output file=%s (%o)" % (output_filename, u))
    
    bytes_read = 0
    while True:
        data = os.read(input_fd, 2<<15)
        
        if not data:
            break
            
        bytes_read += len(data) 
        output_file.write(data)

    log.stderr("hpfax: Wrote %d bytes" % bytes_read)
    
    output_file.close()
    os.close(input_fd)
    
    try:
        os.chown(output_filename, uid, gid)
    except OSError:
        pass
        
    
    
    if not bytes_read:
        log.error("No data!")
        sys.exit(1)
    else:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sock.connect((prop.hpssd_host, prop.hpssd_port))
        except socket.error:
            log.error("Unable to contact HPLIP I/O (hpssd).")
            sys.exit(1)
        else:
            try:
                service.sendEvent(sock, 
                                  EVENT_QUEUE_FAX_JOB, 
                                  'event', 
                                  job_id, 
                                  username,
                                  device_uri, 
                                  {'fax-file': output_filename, 
                                   'printer': printer_name,
                                   'title': title,
                                   'options': options})
                                   
            except Error:
                log.error("Unable to send event to HPLIP I/O (hpssd).")
                sys.exit(1)
        
        sock.close()
    
    sys.exit(0)
