#!/usr/local/bin/perl -- # -*-Perl-*-

# $Id: rfax,v 3.8 1995/02/14 21:36:13 juphoff Exp $

# rfax -- Sends files to remote machine for spooling and faxing.
# Copyright (C) 1994 Jeffrey A. Uphoff
# 
# 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., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
# 
# Jeffrey A. Uphoff
# National Radio Astronomy Observatory
# 520 Edgemont Road
# Charlottesville, VA 22903, USA
# 
# Phone:     (804) 296-0208
# Internet:  juphoff@nrao.edu
# UUCP:      Use pony express instead--it's faster.

# Usage is "rfax [-v] [-s server] [-h]|[-q]|[-r job]|[[-n] [-t to] phone-number file]"


$0 = "rfax @ARGV";		# Set the process name.

require 'sys/socket.ph';
require 'getopts.pl';


# If the host you run this from supports RFC931-compliant user-authentication
# (a la identd), any user information sent in the fax will be overridden by
# the username that this host reports to the fax server.

# More secure than environment variables, but doesn't take su's into account:
chop($user = `logname 2> /dev/null`);
($user = $ENV{'USER'} || $ENV{'LOGNAME'}) unless $user;	# Less secure...

# Insanity check #1.
die "You don't have a username???\n" unless $user;

($fullname = (getpwnam($user))[6]) =~ s/,.*//;

$faxserver = $ENV{'FAXSERVER'};	# Find what server to use.
if(! $faxserver) {		# OK, not in evironment...check these in order.
    if(open(RCFILE, "$ENV{'HOME'}/.faxrc")) {
	chop($faxserver = <RCFILE>);
    } elsif(open(RCFILE, '/etc/faxrc')) {
	chop($faxserver = <RCFILE>);
    } elsif(open(RCFILE, '/usr/local/etc/faxrc')) {
	chop($faxserver = <RCFILE>);
    }
}
close RCFILE if RCFILE;		# May do more with this file in the future...

&Getopts('fhnqvr:s:t:');
((print "Server: $faxserver\n") && exit ) if $opt_h;
$faxserver = $opt_s if length $opt_s;

die "No FAX server specified.  Set FAXSERVER in your environment, or specify the
server on the command line with the -s option.\n"
    unless length $faxserver || ( $#ARGV == 0 );

&checkqueue($opt_q) if $opt_q;	# Just a queue-check.
&removal if $opt_r;		# Removing a queued entry.
&runqueue_only if $opt_f;	# Just flushing things...

# Sanity check #1.
die "Usage:  rfax [options] phone-number file
             -v             be verbose
             -s server      server to send FAX through
             -t name        specify recipient's name (for cover pages, etc.)
             -n             send FAX in \"normal\" resolution
             -r job         remove 'job' from queue
             -h             display default server (host) and exit
             -q             display queued entries and exit
             -f             Force queue run (send all queued entries)

Note: Submitting a FAX job implies a queue run on some servers.
"
    unless $#ARGV == 1;

$phone = @ARGV[0];		# Who ya' gonna' call?
shift;

# Sanity check #2.
die "Invalid phone number: $phone\n" unless $phone =~ /^[\-\d,]*$/;
# Sanity check #3.
die "Can't open file: $ARGV[0]\n" unless -r $ARGV[0] && -f $ARGV[0];

# Make a filename from a path for remote spool.
($filename = $ARGV[0]) =~ s^/^:^g;

select((select(STDOUT), $| = 1)[0]);
&checkqueue(0);

unless(fork) {			# Child takes care of all the work.
    while(<>) {
	print SOCKET;
    }
    print SOCKET "\n%%%FAX recipient: $opt_t%%%\n";
    print SOCKET "%%%FAX phone number: $phone%%%\n";
    print SOCKET "%%%FAX from: $user%%% $fullname %%%\n";
    print SOCKET "%%%FAX filename: $filename%%%\n";
    print SOCKET "%%%FAX TERMINATOR%%%\n";
    &ending_feedback;
}

exit;				# Parent.


# Functions.

sub opensocket
{
    local($faxserver_addr) = (gethostbyname($faxserver))[4];
    die "Invalid remote address: $faxserver\n" unless $faxserver_addr;
    local($port, $protocol) = (getservbyname('fax', 'tcp'))[2..3];
    local($remote_sock) = pack('S n a4 x8', &AF_INET, $port, $faxserver_addr);
    socket(SOCKET, &AF_INET, &SOCK_STREAM, $protocol) || die "socket: $!\n";
    connect(SOCKET, $remote_sock) || die "connect: $!\n";
    select((select(SOCKET), $| = 1)[0]);
}

sub checkqueue
{
    &opensocket;
    print SOCKET "%%%VERBOSE%%%\n" if $opt_v;
    
    if($_[0]) {			# Just checking queue.
	print SOCKET "%%%CHECK QUEUE ONLY%%%\n";
	&ending_feedback;
    } else {			# Sending a fax after this.
	print STDOUT "Sending to $faxserver...\n";
	print SOCKET "%%%NORMAL RESOLUTION%%%\n" if $opt_n;
	print SOCKET "%%%CHECK QUEUE%%%\n";
	print "Entries queued in front of yours:\n";

	while(<SOCKET>) {
	    last if /^%%%END OF QUEUE%%%$/;
	    print "$_" unless /^%%%BEGINNING OF QUEUE%%%$/;
	}
    }
}

sub runqueue_only
{
    &opensocket;
    print SOCKET "%%%RUN QUEUE ONLY%%%\n";
    &ending_feedback;
}

sub removal
{
    &opensocket;
    print SOCKET "%%%REMOVE: $opt_r%%%$user%%%\n";
    &ending_feedback;
}

sub ending_feedback
{
    while(<SOCKET>) {
	print;
    }
    exit;			# Child.
}
