#!/bin/sh
#    $Id: common-functions.sh.in,v 1.23 2006/11/22 18:38:35 aidan Exp $

#
# This holds various functions that are common to the
# various bin scripts.
#

#
# For getting all of the "faxinfo" items to line up.
#
setInfoSize()
{
    INFOSIZE=0
    for ITEM in DICTSENDER DICTPAGES DICTQUALITY DICTSIZE DICTRECEIVED \
		DICTTIMETORECV DICTSIGNALRATE DICTDATAFORMAT DICTERRCORRECT \
		DICTCALLID1 DICTCALLID2 DICTCALLID3 DICTCALLID4 DICTCALLID \
		DICTCALLID6 DICTCALLID7 DICTRECEIVEDON DICTCOMMID; do
	THISLEN="`eval echo "$"$ITEM | wc -m | $SED 's/ //g'`"
	if [ $THISLEN -gt $INFOSIZE ]; then INFOSIZE=$THISLEN; fi
    done
}

#
# For getting all of the notify job items to line up.
#
setItemSize()
{
    ITEMSIZE=0
    for ITEM in DICTDESTINATION DICTJOBID DICTGROUPID DICTSENDER DICTMAILADDR \
		DICTCOMMID DICTMODEM DICTSUBMITTEDFROM DICTPAGEWIDTH \
		DICTPAGELENGTH DICTRES DICTSTATUS DICTDIALOGS DICTDIALS \
		DICTCALLS DICTPAGES DICTATTEMPTS DICTDIRNUM DICTRECEIVER DICTQUALITY \
		DICTPAGEWIDTH DICTPAGELENGTH DICTDATAFORMAT DICTREMOTEEQUIPMENT \
		DICTREMOTESTATION DICTSIGNALRATE; do
	THISLEN="`eval echo "$"$ITEM | wc -m | $SED 's/ //g'`"
	if [ $THISLEN -gt $ITEMSIZE ]; then ITEMSIZE=$THISLEN; fi
    done
}

faxInfo()
{
    $INFO -n $1 | $SED -e "s/^ *Sender:/`printf %$INFOSIZE\s "$DICTSENDER"`:/g" \
		-e "s/^ *Pages:/`printf %$INFOSIZE\s "$DICTPAGES"`:/g" \
		-e "s/^ *Quality:/`printf %$INFOSIZE\s "$DICTQUALITY"`:/g" \
		-e "s/^ *Page:/`printf %$INFOSIZE\s "$DICTSIZE"`:/g" \
		-e "s/^ *Received:/`printf %$INFOSIZE\s "$DICTRECEIVED"`:/g" \
		-e "s/^ *TimeToRecv:/`printf %$INFOSIZE\s "$DICTTIMETORECV"`:/g" \
		-e "s/^ *SignalRate:/`printf %$INFOSIZE\s "$DICTSIGNALRATE"`:/g" \
		-e "s/^ *DataFormat:/`printf %$INFOSIZE\s "$DICTDATAFORMAT"`:/g" \
		-e "s/^ *ErrCorrect:/`printf %$INFOSIZE\s "$DICTERRCORRECT"`:/g" \
		-e "s/^ *CallID1:/`printf %$INFOSIZE\s "$DICTCALLID1"`:/g" \
		-e "s/^ *CallID2:/`printf %$INFOSIZE\s "$DICTCALLID2"`:/g" \
		-e "s/^ *CallID3:/`printf %$INFOSIZE\s "$DICTCALLID3"`:/g" \
		-e "s/^ *CallID4:/`printf %$INFOSIZE\s "$DICTCALLID4"`:/g" \
		-e "s/^ *CallID5:/`printf %$INFOSIZE\s "$DICTCALLID5"`:/g" \
		-e "s/^ *CallID6:/`printf %$INFOSIZE\s "$DICTCALLID6"`:/g" \
		-e "s/^ *CallID7:/`printf %$INFOSIZE\s "$DICTCALLID7"`:/g" \
		-e "s/ Yes$/ $DICTYES/g" \
		-e "s/ No$/ $DICTNO/g" \
		-e "s/ Normal$/ $DICTNORMAL/g" \
		-e "s/ Fine$/ $DICTFINE/g"
}

parseQfile()
{
    # In shell scripts, there are no special characters in hard-quoted
    # strings (quoted with (')). Single-quotes can't even be escaped
    # inside such strings and must be put outside of them. We thus replace
    # (') with ('\'') which terminates the current string, adds a single
    # quote and starts a new string.
#
    # We no longer escape newlines, because we don't eval
    #
    # print out variable name and value so we can eval it in the shell
    #
    AWK_OUTPUT=`$AWK -F: ' 
    function p(varname,val)
    {
        gsub(/\\047/, "\047\\\\\047\047", val);
        printf "%s=\\047%s\\047\n",varname,val
        printf "export %s\n",varname
    }
    BEGIN {
        nfiles = 0;
        npins = 0;
        pagewidth = 0;
        pagelength = 0;
        resolution = 0;
        jobtype = "facsimile";
        signalrate = "unknown";
        dataformat = "unknown";
        doneop = "default";
        pagernum = "unknown";
        commid = "";
	csi = "";
	equipment = "";
	station = "";
    }
    /^csi/	{ p("csi",$2); }
    /^nsf/	{ p("equipment",$3); }
    /^nsf/	{ p("station",$5); }
    /^jobid/    { p("jobid",$2); }
    /^groupid/    { p("groupid", $2); }
    /^state/    { p("state", $2+0); }  
    /^doneop/    { p("doneop", $2); }
    /^number/    { p("number", $2); }
    /^external/    { p("number", $2); }        # override unprocessed number
    /^receiver/    { p("receiver", $2); }
    /^company/    { p("company", $2); }
    /^sender/    { p("sender", $2); }
    /^mailaddr/    { p("mailaddr", $2); }
    /^owner/    { p("owner", $2); }
    /^jobtag/    { jobtag = $0; sub("jobtag:", "", jobtag); p("jobtag", jobtag)}
    /^jobtype/    { p("jobtype", $2); }
    # status needs to be used in the shell as faxstatus since status is reserved word
    /^status/    { status = $0; sub("status:", "", status);
              while ($0 ~ /\\\\$/ && getline > 0) {
                  sub(/\\\\$/, "\\n", status);
                  status = status $0;
              } p("faxstatus", status);
            }
    /^resolution/    { p("resolution", $2); }
    /^npages/    { p("npages", $2); }
    /^totpages/    { p("totpages", $2); }
    /^dirnum/    { p("dirnum", $2); }
    /^commid/    { p("commid", $2); }
    /^ntries/    { p("ntries", $2); }
    /^ndials/    { p("ndials", $2); }
    /^pagewidth/    { p("pagewidth", $2); }
    /^pagelength/    { p("pagelength", $2); }
    /^signalrate/    { p("signalrate", $2); }
    /^dataformat/    { p("dataformat", $2); }
    /^modem/    { p("modem", $2); }
    /^totdials/    { p("totdials", $2); }
    /^tottries/    { p("tottries", $2); }
    /^client/    { p("client", $2); }
    /^[!]*post/    { p("files_"++nfiles, $4); p("filetype_"nfiles, "PostScript"); }
    /^[!]*tiff/    { p("files_"++nfiles, $4); p("filetype_"nfiles, "TIFF"); }
    /^[!]*pdf/    { p("files_"++nfiles, $4); p("filetype_"nfiles, "PDF"); }
    /^[!]*pcl/    { p("files_"++nfiles, $4); p("filetype_"nfiles, "PCL"); }
    /^page:/    { p("pins_"++npins, $4); }
    /^data:/    { p("files_"++nfiles, $4); }
    /^poll/        { p("poll", " -p"); }
    END { p("nfiles", nfiles); p("npins", npins) } ' $QFILE `
    eval "$AWK_OUTPUT"

}

parseFaxInfo()
{
    # We use the same basic stuff as parseQfile(), but just to straight assignment
    AWK_OUTPUT=`$INFO -S '' -s '%s=!=!=!=!=!=!=!=!=' $1 | $AWK -F'=!=!=!=!=!=!=!=!=' '
    function p(varname,val)
    {
        gsub(/\\047/, "\047\\\\\047\047", val);
        printf "%s=\\047%s\\047\n",varname,val
        printf "export %s\n",varname
    }
    { p(toupper($1),$2); }
    '`
    eval "$AWK_OUTPUT"
}

#
# Produce mailable encoding for binary files.
# mimeEncode(filename, encoding)
# If encoding is not set, will default to $ENCODING.
#
mimeEncode()
{
    if [ ! -f "$1" ] ; then
        return # cannot do much more without a file
    fi
    if [ -n "$2" ] ; then
        encoding=$2;
    else
        encoding=$ENCODING;
    fi
    encoding=`echo $encoding | $SED -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`

    # Configuration for which faxsetup was not rerun contains $MIMENCODE
    # rather than separate $BASE64ENCODE and $QPENCODE
    case "$encoding" in
        base64)
	    if [ -n "$BASE64ENCODE" ]; then
		# $BASE64ENCODE may contain parameters
		cmd=`echo $BASE64ENCODE | $SED -e "s/^ *//" -e "s/ .*$//"`
		if [ -x "$cmd" ]; then
		    ($BASE64ENCODE < $1 \
			| $GREP -v "====$") \
			2>$ERRORSTO
		fi
	    # For compatibility with earlier configurations:
	    elif [ -x "$MIMENCODE" ]; then
		$MIMENCODE < $1 2>$ERRORSTO
	    elif [ -x "$UUENCODE" ]; then
		($UUENCODE -m ==== < $1 \
		    | $GREP -v "====$") \
		    2>$ERRORSTO
	    fi;;
        quoted-printable)
	    if [ -n "$QPENCODE" ]; then
		# $QPENCODE may contain parameters
		cmd=`echo $QPENCODE | $SED -e "s/^ *//" -e "s/ .*$//"`
		if [ -x "$cmd" ]; then
		    $QPENCODE < $1 2>$ERRORSTO
		fi
            # For compatibility with earlier configurations:
	    elif [ -x "$MIMENCODE" ]; then
		# Take a chance that $MIMENCODE really contains mimencode
		$MIMENCODE -q < $1 2>$ERRORSTO
	    fi;;
        *uue*)
	    if [ -x "$UUENCODE" ]; then
		($UUENCODE ==== < $1 | grep -v "====$") 2>$ERRORSTO
	    fi;;
        *) cat $1;; # 7bit, 8bit, binary
    esac
}

#
# "Template" STDIN, by subsituting $... with the actual environment
# variable $..., writing to STDOUT, using $AWK
template ()
{
        cat - | $AWK '
	function include_file (file)
	{
		while (getline bla<file )
		{
			template_line(bla);
		}

	}
	function template_line (line,   tmp,var)
        {
                while (match(line, /[$][A-Za-z0-9_]+/))
                {
			if (substr(line,RSTART-1,1) == "\\")
			{
				tmp = substr(line, 1, RSTART-2);
				var = substr(line, RSTART+1, RLENGTH-1);
				printf "%s$%s", tmp, var
			} else
			{
				tmp = substr(line, 1, RSTART-1);
				var = substr(line, RSTART+1, RLENGTH-1);
				printf "%s%s", tmp, ENVIRON[var];
			}
			line = substr(line,RSTART+RLENGTH)
                }
		if (match(line, /^[#]INCLUDE /))
		{
			include_file(substr(line,10));
			return
		}
                print line;
        }

        {
                template_line($0);
        }'
}

#
# CreateMailMessage <template> [<attach1> <type1> <name1> <desciption1> 
#		[<attach2> <type2> <name2> <description2> 
#			...] ]
#
# This creates a mail message based on <template>, and attaches
# The given files as MIME attachments
#
# The "template" section takes it's Content-* lines right from the
# template, so whoever is doing the templates can control the
# content-type and encoding directly

# The files are all attached with the following:
#	Content-type: <type>; name=<name>
#	Content-Description: <description>
#	Content-Disposition: attachment; filename="<name>"
#	Content-encoding: $ENCODING
CreateMailMessage ()
{
    # First we take the top part of the e-mail for headers
    # Excluding any "Content-" lines, which need to stay with
    # the actual template content
    $SED -n -e '/^$/q;p' $1			\
    	| $GREP -v "^Content"		\
	| template

    # If there are attachments, we are a multipart/mixed
    echo "Mime-Version: 1.0"
    if [ -n "$2" ]; then
	echo "Content-Type: Multipart/Mixed; Boundary=\"$MIMEBOUNDARY\""
	echo ""
	echo "--$MIMEBOUNDARY"
    fi

    # Now print the Content-* headers for the template
    $SED -n -e '/^$/q;p' $1			\
    	| $GREP "^Content"		\
	| template

    echo ""
    body_encoding=`$SED -n -e '/^$/q;p' $1		\
    	| $GREP -i "^Content-Transfer-Encoding"	\
	| template				\
    	| $SED -e 's/^[^ ]*: *//'`;
    test "$body_encoding" || body_encoding=7bit;

    $SED -n -e '1,/^$/d;p' $1 | template > $TMPDIR/body.txt
    mimeEncode $TMPDIR/body.txt $body_encoding

    if [ -n "$2" ]; then
	shift
	while [ -n "$1" ]
	do
	    echo "--$MIMEBOUNDARY"
	    echo "Content-Type: $2; name=\"$3\""
	    echo "Content-Description: $4"
	    echo "Content-Disposition: attachment; filename=\"$3\""
	    echo "Content-Transfer-Encoding: $ENCODING"
	    echo ""
	    mimeEncode $1
	    shift; shift; shift; shift;
	done
	echo "--$MIMEBOUNDARY--"
    fi
}


## A Simple function to trace stuff
## to STDERR, not STDOUT
TraceLog ()
{
    echo $* 1>&2
}

## ConvertFile <file> <oldtype> <newtype>
## Convert $1 from $2 to type $3
##
## This will (possibly) create a tempoary file
## in the Private $TMPDIR area for the new file
## If the original file is in the proper form, no
## new file will be created
##
## It prints the file name of the converted
## file to stdout
ConvertFile ()
{
    case "$3" in
	PostScript|postscript|PS|ps)
	    TraceLog "Converting $1 to Postscript"
	    case $2 in
		PostScript|Postscript|PS|ps)
		    TraceLog "No conversion"
		    echo $1
		    ;;
		PDF|pdf)
		    TraceLog "pdf2ps necessary"
		    name="`basename $1 .pdf`"
		    $PDF2PS $1 $TMPDIR/$name.ps
		    echo "$TMPDIR/$name.ps"
		    ;;
	    	TIFF|tiff|TIF|tif)
		    TraceLog "tiff2ps necessary"
		    name="`basename $1 .tif`"
		    $TIFF2PS -a $1 > $TMPDIR/$name.ps
		    echo "$TMPDIR/$name.ps"
		    ;;
	    esac
	    ;;
	PDF|pdf)
	    TraceLog "Converting $1 to PDF"
	    case $2 in
	    	PostScript|Postscript|PS|ps)
		    TraceLog "Using ps2pdf"
		    name="`basename $1 .ps`"
		    $PS2PDF $1 $TMPDIR/$name.pdf >/dev/null 2>&1
		    echo "$TMPDIR/$name.pdf"
		    ;;
		PDF|pdf)
		    TraceLog "Nothing necessary"
		    ;;
		TIFF|tiff|TIF|tif)
		    TraceLog "Using tiff2pdf"
		    name="`basename $1 .tif`" $TIFF2PDF  -o $TMPDIR/$name.pdf $1 echo "$TMPDIR/$name.pdf"
	    esac
	    ;;
	TIFF|TIF|tif|tiff)
	    TraceLog "Converting $1 to TIFF"
	    case $2 in 
	    	PostScript|Postscript|PS|ps)
		    TraceLog "Using ps2fax"
		    name="`basename $1 .ps`"
		    $PS2FAX -r $resolution $1 $TMPDIR/$name.tif
		    echo "$TMPDIR/$name.tif"
		    ;;
	    	PDF|pdf)
		    TraceLog "Using pdf2fax"
		    name="`basename $1 .pdf`"
		    $PDF2FAX -r $resolution $1 $TMPDIR/$name.tif
		    echo "$TMPDIR/$name.tif"
		    ;;
		TIFF|tiff|TIF|tif)
		    TraceLog "Nothing neccessary"
		    ;;
	    esac
	    ;;
	*)
	    TraceLog "Ignoring $1 to \"$3\""
	    ;;
    esac

}

LocalSequence ()
{
    if [ $1 -gt $2 ]; then
	    return
    fi
    COUNT=$1
    while [ $COUNT -le $2 ]
    do
	echo $COUNT
	COUNT=`expr $COUNT + 1`
    done
}

SetupPrivateTmp()
{
    TMPDIR="/tmp/tmp-$$"

    mkdir -m 0700 "$TMPDIR"
    if [ $? != 0 ]
    then
	echo "Couldn't setup private temp area - exiting!" 1>&2
	exit 1
    fi
}

CleanupPrivateTmp ()
{
    if [ -d "$TMPDIR" ]
    then
	case "$TMPDIR" in
	    "/tmp/tmp-$$")
		rm -Rf "$TMPDIR"
		;;
	    *)
		echo "Cleanup of temporary dir fail: Bad dir $TMPDIR" 1>&2
		;;
	esac
    fi
}


