#!/usr/bin/env perl
#
# Hinweis:	Tabulatorbreite: 4 Zeichen
#			(automatische Einstellung fr ViM durch letzte Zeile)
# Notice:   tab width: 4 characters
#			(this is done for ViM automatically through the	last line)
#
########################################################################
#                                                                      #
#    Muttprint - erleichtert das Drucken von Mails                     #
#    Copyright  2000-03, Bernhard Walle <bernhard.walle@gmx.de>       #
#                                                                      #
#    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 Mass Ave, Cambridge, MA 02139, USA.         #
#                                                                      #
#    You find the GPL in the file "COPYING" which was distributed      #
#    with Muttprint. For a German tranlation look at                   #
#                                                                      #
#    http://www.suse.de/de/linux/gpl/index.html                        #
#                                                                      #
########################################################################

# Deklaration erzwingen
use strict;
# Deklaration nach Perl-5.005-Art
use vars qw($VERSION %Config $LPack $charset $texFontenc %String);
use sigtrap qw(die INT QUIT TERM);
use POSIX;
use File::Temp qw(tempdir);


# richtig und falsch
use constant TRUE 	=> 1;
use constant FALSE	=> 0;


############# BEGIN VARIABLES ################################################


$VERSION = "0.71";

my $PACKAGE = "Muttprint";


######## Subroutinen mit Prototypes
sub readConfig (@);
sub readOpts ();
sub getPaperConfig ();
sub findCommonDir ($);
sub createLatex ();
sub getRealname ($);
sub getShortFrom($$);
sub getNumberOfPages ($);
sub copyFile ($$);
sub printDuplexNoCups ($$$$);
sub printDuplexCups ($$$);
sub modifyPS ($);
sub createTemp ();
sub setStrings ($);
sub writeFormated ($*$);
sub decodeHeader();
sub getDefaultPrinterCDE();
sub changeForXface($);
sub getCharset($);
sub convertDate($);
sub getISOlatinExtensions($);

######## 'private' Variablen fr den Rest
%Config = (
	PRINTER			=> 	'',
	PRINT_COMMAND	=>	'lpr -P$PRINTER',
	PENGUIN			=>	'on',
	DUPLEX			=>	'off',
	SPEED			=>	'30',
	PAPERSAVE		=>	'off',
	FONT			=>	'Latex',
	PAPER			=>	'A4',
	DEBUG			=>	'1',
	REM_SIG			=>	'off',
	REM_QUOTE		=>	'off',
	WAIT			=>	'30',
	TOPMARGIN		=>	'19',
	BOTTOMMARGIN	=>	'22',
	LEFTMARGIN		=>	'20',
	RIGHTMARGIN		=>	'20',
	HEADRULE		=>	'off',
	FOOTRULE		=>	'off',
	FRONTSTYLE		=>	'border',
	MAXADDR		    =>	'10',
	DATE			=>	'original',
	DATE_FORMAT		=>	'%c',
	XFACE			=>	'off',
	PRINTED_HEADERS	=>	'Date_To_From_CC_Newsgroups_*Subject*',
	FONTSIZE		=>	'10pt',
	WRAPMARGIN		=>	80,
	VERBATIMNORMAL	=>	'',
	VERBATIMSIG		=>	'fontshape=it',
	RCFILE			=>	'',
	ADDRESSFORMAT	=>	'%r <%a>,\n',
	LATEXCODE		=>	'',
	LATEXCODE1		=>	'',
	SIG_REGEXP		=>	'^-- $',
	LATEXCODE2		=>	'',
	LATEXCODE3		=>	'',
	LATEXCODE4		=>	'',
	LATEXCODE5		=>	'',
	FOREGROUND		=>	0,
);
my %fontpackages = (
	'Latex'    		=>		'',
	'Latex-bright'	=>		'cmbright',
	'Times'			=>		'mathptmx,courier',
	'Charter'		=>		'charter',
	'Utopia'		=>		'utopia',
	'Palatino'		=>		'mathpple,courier',
	'Bookman'		=>		'bookman',
	'CentSchool'	=>		'newcent',
	'Chancery'		=>		'chancery,courier',
	'Helvetica'		=>		'helvet-SANSSERIF-,courier',
	'AvantGarde'	=>		'avant-SANSSERIF-,courier',
);
my %EuroSign = (
	'Latex'			=>		'\EURtm{}',
	'Latex-bright'	=>		'\EURhv{}',
	'Times'			=>		'\EURtm{}',
	'Charter'		=>		'\EURtm{}',
	'Utopia'		=>		'\EURtm{}',
	'Palatino'		=>		'\EURtm{}',
	'Bookman'		=>		'\EURtm{}',
	'CentSchool'	=>		'\EURtm{}',
	'Chancery'		=>		'\EURtm{}',
	'Helvetica'		=>		'\EURhv{}',
	'AvantGarde'	=>		'\EURhv{}',
);
my $Lang = "en";							# Sprache
my @print;									# ob Hilfe / Version angezeigt werden soll
my %Temp;									# temporre Dateien und Verzeichn.
my %Header;									# Header ...
my @PrintedMailheaders;						# Mailheader so wie er gedruckt wird (LaTeX-Code)
my $childPid;								# PID des Kinds
my $DVIopts;								# Optionen fr DVI - Aufruf
my @Command;								# Kommando zum Drucken; fr Druck in Datei
my $Laenge = "0";							# zum Ermitteln der lngsten Zeile
my $MaxLaenge = "0";						# die lnste Zeile
my $QP = 0;									# quoted printable encoded body
my @LastHeader = ("", 0);					# letzter gefundener Header
											# (Header, Zeilen#)
my %HeaderFormatAttr;						# Formatauszeichnungen in LaTeX-Code
my @headers;
my $image_height = "20mm";					# Hhe des gedruckten Bildes
my $startworkingdir = getcwd();				# Arbeitsverzeichnis, wenn Muttprint
											# gestartet wird
my $signature;								# Signatur (Inhalt)


############# END VARIABLES ##################################################



#
# Konfiguration einlesen

$Config{PRINTER} = $ENV{PRINTER} if defined $ENV{PRINTER};

#
# CDE default printer
{
	my $CDEprinter = getDefaultPrinterCDE();
	if ($CDEprinter) {
		$Config{PRINTER} = $CDEprinter;
	}
}

$Config{PAPER} = getPaperConfig ();
readConfig ("/etc/Muttprintrc", "$ENV{HOME}/.muttprintrc");


@print = readOpts ();

if ($Config{'PENGUIN'} eq "on") {
	my $sharedir = findCommonDir("share");
	$Config{'PENGUIN'} = (-r "$sharedir/penguin.eps")
			? "$sharedir/penguin.eps" 
			: "off";
}

readConfig ($Config{RCFILE});



################ MULIT LANGUAGE SUPPORT #######################################

$Lang = $ENV{'LANG'} if defined $ENV{'LANG'};
$Lang = $Config{'LANG'} if defined $Config{'LANG'};
POSIX::setlocale(&POSIX::LC_ALL, $Lang);

setStrings($Lang);

#
# Show help and version
#
# 0 => help (return 0)
# 1 => version
# 2 => error -> help (return 1)

if ($print[0]) {
	print "\n".$String{'Benutzung'}."\n\n".$String{'Bugs'}."\n\n";
	exit 0;
} 
elsif ($print[1]) {
	print "\n"."Muttprint $VERSION"."\n\n".$String{'Lizenz'}."\n\n";
	exit 0;
} 
elsif ($print[2]) {
	print "\n".$String{'Benutzung'}."\n\n".$String{'Bugs'}."\n\n";
	exit 1;
}


# default settings 
# we need to set this here because we want that configuration file
# options overwrite language file options but we need to read the
# configuration file first because in this file the language can
# be set (some sort of hen-egg-problem)

if (!defined $Config{CHARSET}) {
	$Config{CHARSET} = $charset ? $charset : 'latin1';
}
if (!defined $Config{LPack}) {
	$Config{LPack} = $LPack ? $LPack : 'english';
}
if (!defined $Config{TEX_FONTENC}) {
	$Config{TEX_FONTENC} = $texFontenc ? $texFontenc : 'T1';
}

# USE FOR DEBUG ONLY
if ($Config{DEBUG}) {
	my @configs;
	foreach (keys %Config) {
		if (defined $Config{$_}) {
			push (@configs, sprintf("%-20.20s  => %-40.40s\n", $_, $Config{$_}));
		}
	}
	@configs = sort(@configs);
	print "=" x 70, "\n";
	foreach (@configs) { print; }
	print "=" x 70, "\n";
}


#
# Some printer settings. We need this here because of the `no real mail' case
#

# Using cups
if ($Config{PRINT_COMMAND} eq "CUPS") {
	$Config{PRINT_COMMAND} = 'lpr $CUPS_OPTIONS';
}

#
# are we using cups?
my $useCups = ( ($Config{PRINT_COMMAND} =~ /\$CUPS_OPTIONS/) && 
		($Config{PRINTER} !~ /^TO_FILE/) )
	? 1
	: 0;

# Need to substitute in the printer name if the printer was
# set. If not we use 'lp' as a fallback printer name
if ($Config{PRINTER}) {
	if ($useCups) {
		$Config{PRINT_COMMAND} =~ s/\$CUPS_OPTIONS/ -P $Config{PRINTER} \$CUPS_OPTIONS/;
	}
	# no else case because $CUPS_OPTIONS and $PRINTER could be both in PRINT_COMMAND
	$Config{PRINT_COMMAND} =~ s/\$PRINTER/$Config{PRINTER}/g;
} else {
	$Config{PRINT_COMMAND} =~ s/\$PRINTER/lp/g;
}

#
# Formatierung fr Header
foreach (split (/_/, $Config{'PRINTED_HEADERS'})) {
	my $unformated = $_;
	my $formats = "";
	$unformated =~ s/[\*\/]//g;
	
	$formats .= '\\bfseries' if /\*.*\*/;
	$formats .= '\\itshape' if /\/.*\//;
	
	$HeaderFormatAttr{$unformated} = $formats;
	push @headers, $unformated;
}

{
	my @KompletteMail = <>;
	my $mail_charset;

	my $Content;

	my $signature_mode;
	my $sig_mod_counter = 0;

	for (my $i = 0; $_ = $KompletteMail[$i]; $i++) {
	
		$. = $i;

		# for software that outputs \r\n-line-Endings
		s/[\r\f]+//g;
	
		#
		# signature 
		if (((/$Config{SIG_REGEXP}/o && !($Config{REM_SIG} eq "on")) ||
			$signature_mode) && $Config{VERBATIMSIG} ne "raw") {

			if (/$Config{SIG_REGEXP}/o) {
				$signature_mode = TRUE;

				# Leerzeile bei 2. Signatur
				if (defined $signature) {
					$signature .= "\n";
				}
			} 
			else {
				$signature .= $_;
			}

			# 2 Leerzeilen => Ende der Signatur
			if (/^$/ and $sig_mod_counter == 0) {
				$sig_mod_counter++;
			} elsif (/^$/ and $sig_mod_counter == 1) {
				$signature_mode = FALSE;
			} else {
				$sig_mod_counter = 0;
			}

			next;
		}
	
		#
		# and what's about Quoting?
		next if (($Config{'REM_QUOTE'} eq "on") && (/^([\t]*[|>:}#])+/));
	
	
		#
		# Do sth with the header
		if (0 ... /^$/) {
	
			my $aktHeader;
		
			$QP = 1 if /^Content-Transfer-Encoding:[\t ]+quoted-printable/i;
			($mail_charset) = /charset=(["'A-Za-z0-9\-_]*)/i unless $mail_charset; 
			
			foreach $aktHeader (@headers, "X-Face") {
			
				if (/^${aktHeader}:[\t ]+/i) {
					@LastHeader = ($aktHeader, $.);
					if (exists $Header{$aktHeader}) {
						$Header{$aktHeader} .= "\n ";
					}
					chomp($Header{$aktHeader} .= $');
				} 
				elsif (/^[\t ]+/i && ($LastHeader[1] + 1 == $.)) {
					chomp($Header{"$LastHeader[0]"} .= " $'");
					$LastHeader[1] ++;
				}
			}
		}
	
	
		#
		# ... and do sth with the body
		else {
	
			$Content .= $_;
				
			$Laenge = length($_);
			$MaxLaenge = $Laenge if ($Laenge > $MaxLaenge);
		
		}
	}

	# ab in den Hintergrund 

    unless ($Config{DEBUG} || $Config{FOREGROUND}) {
    	fork && exit;
    }

	#
	# wenn die Header nicht ausgelesen werden knnen: so drucken!		
	unless ($Header{'From'} || $Header{'To'} || $Header{'Subject'}) { 

		$Config{PRINT_COMMAND} =~ s/\$CUPS_OPTIONS//g;
        
		open (PRINTER, "| $Config{PRINT_COMMAND}") 
        || die "unable to print with $Config{PRINT_COMMAND}: $!";
		print PRINTER @KompletteMail;
		close PRINTER;
		exit;
	
	}


	# formatieren
	
	# Body dekodieren
	if ($QP) {
		$Content =~ s/=([A-Fa-f0-9]{2})/chr(hex($1))/eg;
	}

	createTemp();
	open (CONTENT, "> $Temp{'content'}") || die "unable to create $Temp{'content'}: $!";

	if ($MaxLaenge > $Config{WRAPMARGIN}) {
		writeFormated($Content, \*CONTENT, $Config{WRAPMARGIN});
	
	} else {
		print CONTENT $Content;
	}

	close CONTENT;

	# Zeichensatz automatisch erkennen
	if ($Config{CHARSET} eq "auto") {
		$Config{CHARSET} = $mail_charset ? getCharset($mail_charset) : "latin1";
	}

}


# Realname
$Header{'ShortFrom'} = getShortFrom ($Header{'From'}, $Header{'To'});

#
# passendes Eurozeichen
my $EuroSign = '\EURtm{}';
if (exists $Config{FONT} and exists $EuroSign{$Config{FONT}}) {
	$EuroSign = $EuroSign{$Config{FONT}};
}


my $type;
my %Count;
foreach $type (@headers) {
	
	if (defined $Header{$type}) {
		
		if ($type =~ /^Date/i) {
			$Header{$type} =~ s/-/--/;

			# Datum konvertieren
			if ($Config{DATE} eq "local") {
				$Header{Date} = convertDate($Header{Date});
			}
		}
		else {
			for ($Header{$type}) {
				
				decodeHeader();  # for notes, see the Subroutine!!
				
				my $count = 0;
				#
				# Header formatieren nach ADDRESSFORMAT
				if ($type =~ /^(To|From|CC)/i && $Config{ADDRESSFORMAT} ne "original") {
					# Adressen 'einrahmen'
					s/(?:^|\s)([^<>'"\s]+\@[^<>\s,'"]+)/<$1>/g;
					s/<+/</g;
					s/>+/>/g;

					my $spezheader;
					my $newheader;
					foreach $spezheader (split /(?<=>),/, $_) {
						my $realname = getRealname($spezheader) || "";
						my $format = $Config{ADDRESSFORMAT} || "%r <%a>\n";
						my $address = ($spezheader =~ /(?<=<)(\S+\@\S+)(?=>)/)[0] || "";

						if ($count < $Config{MAXADDR}) {
							if ($realname !~ /^\s*$/) {
								$format =~ s/\*(.+)?\*/\0\\textbf\0{$1\0}/g;
								$format =~ s/\/(.+)?\//\0\\textit\0{$1\0}/g;
								$format =~ s/%r/$realname/g;
								$format =~ s/%a/$address/g;
								$format =~ s/\\n/\n/g;
								$newheader .= $format;
							}
							else {
								$newheader .= $format =~ /\n$/ ? "$address,\n" : "$address,";
							}
							$newheader .= " ";
						}
						else {
							if ($count == $Config{MAXADDR})  {
								$newheader .= " \n \0\\ldots ";
								$count++;
							}
						}
						
						$count ++;
						
					}

					$newheader =~ s/[\s,\n]+$//g;
					$_ = $newheader;
				}
					
				s/(?<!\0)\{/\\\{/g;
				s/(?<!\0)\}/\\\}/g;

				if ($type =~ /from|to|cc/i) {
					s/(?<!\0)\\\)/\)/g;
					s/(?<!\0)\\\(/\(/g;
				}

				s/(?<!\0)\\/\\textbackslash\{\}/g;
				s/\n/\\newline/g;
				s/\"/\\textquotedbl\{\}/g;
				s/>/\\textgreater\{\}/g;
				s/</\\textless\{\}/g;
				s/\#/\\\#/g;
				s/\&/\\&/g;
				s/\$/\\\$/g;
				s/\|/\\\|/g;
				s/\~/\\\~{}/g;
				s/\^/\\\^{}/g;
				s/\%/\\\%/g;
				s/_/\\_/g;
				s/-/{-}/g;
				s/\0//g;

				if ($Config{CHARSET} eq "latin1" or $Config{CHARSET} eq "latin9") {
					s/\200/$EuroSign/g;
					if ($Config{CHARSET} eq "latin9") {
						s//$EuroSign/g;
					}
				}
			}
		}

		my $ftype = "\L\u$type";
		$ftype = "Message-ID" if ($ftype eq "Message-id");
		
		unless (defined $String{$ftype}) {
			$String{$ftype} = "$ftype:";
		}
		
		push @PrintedMailheaders,
			"{ $HeaderFormatAttr{$type} $String{$ftype}} \& ".
			"$HeaderFormatAttr{$type} $Header{$type}  \& \\\\ \n";
				
	}
}


# # XFACE-Support

if ($Config{'XFACE'} eq "on" && exists $Header{'X-Face'}) {
	changeForXface($Header{'X-Face'});
}

#
# Papierformat
my $paperformat = ($Config{PAPER} eq "letter")
	? "letter"
	: "a4";

#
# redirection of the error output
my $errorRedirection = $Config{DEBUG}
	? "$Temp{logf}" 
	: "/dev/null";


#
# LaTeX-Datei erzeugen
createLatex();

chdir($Temp{dir});

#
# running latex twice because of the "page ... of ..."
system("latex -interaction=nonstopmode mail.tex >> $errorRedirection 2>&1");
system("latex -interaction=nonstopmode mail.tex >> $errorRedirection 2>&1");

#
# no check of the exit code because we do this here
unless (-e $Temp{dvi}) {
	die "Latex didn't work. There's no DVI file.";
}


##################################### PRINTING ###############################


#
# generating the postscript file in every case
system("dvips -t $paperformat -o $Temp{ps} $Temp{dvi} >> $errorRedirection 2>&1")
	and die "Error while running dvips: $!";


# now we find out the number of pages the document has
my $numberOfPages = getNumberOfPages("$Temp{dir}/mail.aux");

#
# if the papersave mode is `optional' we need to determine whether
# it makes sense to turn papersave on, i.e. if there's more than
# one page to print
if ($Config{PAPERSAVE} eq "optional") {
	$Config{PAPERSAVE} = ($numberOfPages > 1)
		? "on"
		: "off";
}


#
# setting the paperformat for Cups
if ($useCups) {
	$Config{PRINT_COMMAND} =~ s/\$CUPS_OPTIONS/ -o media=\U$paperformat\E \$CUPS_OPTIONS/;
}

#
# papersave mode
if ($Config{PAPERSAVE} eq "on") {
	if ($useCups) {
		$Config{PRINT_COMMAND} =~ s/\$CUPS_OPTIONS/ -o number-up=2 \$CUPS_OPTIONS/;
	} else {
		system("psnup -2 -q $Temp{ps} $Temp{psnew} >> $errorRedirection 2>&1") 
			and die "Psnup failed: $!";
		unlink($Temp{ps});
		link($Temp{psnew}, $Temp{ps});
	}
}

#
# duplex printing with a `real' duplex printer
if ($Config{DUPLEX} eq "printer") {
	if ($Config{PAPERSAVE} eq "on") {
		if ($useCups) {
			$Config{PRINT_COMMAND} =~ 
				s/\$CUPS_OPTIONS/ -o sides=two-sided-long-edge \$CUPS_OPTIONS/;
		} else { # no cups
			modifyPS("landscape");
		}
	} else { # no papersave
		if ($useCups) {
			$Config{PRINT_COMMAND} =~ 
				s/\$CUPS_OPTIONS/ -o sides=two-sided-short-edge \$CUPS_OPTIONS/;
		} else { # no cups
			modifyPS("portrait");
		}
	}
}

#
# simulated duplex printing
if ($Config{DUPLEX} eq "on") {
	if ($useCups) {
		$Config{PRINT_COMMAND} =~ 
				s/\$CUPS_OPTIONS/ -o page-set=oddeven \$CUPS_OPTIONS/;
	} else {
		system("psselect -q -o $Temp{ps} $Temp{ps1} >> $errorRedirection 2>&1")
			and die "Psselect failed: $!";
		system("psselect -q -e $Temp{ps} $Temp{ps2} >> $errorRedirection 2>&1")
			and die "Psselect failed: $!";
	}
}
			

#
# printing in a file
if ($Config{'PRINTER'} =~ /^(TO_FILE|file):[^-]+/i) {
	my $file1 = "$ENV{HOME}/muttprint.ps";
	my $file2 = "$ENV{HOME}/muttprint2.ps";

	$file1 = $Config{PRINTER};
	$file1 =~ s/(TO_FILE|file)://;

	# if not an absoute path
	if ($file1 !~ /\//) {
		$file1 = "$startworkingdir/$file1";
	}

	# do we have two printfiles?
	if ($Config{DUPLEX} eq "on") {
		$file2 = $file1;
		$file2 =~ s/\.(\w+)$/2.$1/;

		# sure is sure
		if ($file1 eq $file2) {
			$file2 .= "2";
		}
	}

	if ($Config{DUPLEX} eq "on") {
		copyFile($Temp{ps1}, $file1);
		copyFile($Temp{ps2}, $file2);
	} else {
		copyFile($Temp{ps}, $file1);
	}
	
} elsif ($Config{'PRINTER'} =~ /^((TO_FILE|file):-?|-)$/i) {
	
	# Just write the postscript code to STDOUT
	open (PS, "<$Temp{ps}") or die "Could not open $Temp{ps} for reading: $!";
	while (<PS>) {
		print $_;
	}
	close PS or die "Could not close $Temp{ps}: $!";

} else { # here's the code for normal printing
	# remove CUPS_OPTIONS here
	$Config{PRINT_COMMAND} =~ s/\$CUPS_OPTIONS//;

	# correct the number of pages to the `real' number
	if ($Config{PAPERSAVE} eq "on") {
		$numberOfPages = POSIX::ceil($numberOfPages/2);
	}
	
	if ( ($Config{DUPLEX} ne "on") || ($numberOfPages == 1) ) {
		# we use the print command as pipe because it's more flexible
		system("cat $Temp{ps} | $Config{PRINT_COMMAND} >> $errorRedirection 2>&1")
			and die "Could not print with $Config{PRINT_COMMAND}: $!";
	} else { # duplex is on
		my $sleepTime = 0;

		# calculating the sleep time
		$sleepTime = $Config{SPEED} * $numberOfPages + $Config{WAIT};

		if ($useCups) {
			printDuplexCups($Config{PRINT_COMMAND}, $Temp{ps}, $sleepTime);
		} else {
			printDuplexNoCups($Config{PRINT_COMMAND}, $Temp{ps1}, $Temp{ps2}, $sleepTime);
		}
	}
}

################################### ENDE ####################################


##################### UNTERFUNKTIONEN ########################################

sub printDuplexNoCups ($$$$) {

	my $printCommand = shift;
	my $firstFile = shift;
	my $secondFile = shift;
	my $timeBetween = shift;

	if (!defined($childPid = fork())) {
		die "kann fork nicht ausfhren: $!";
	} elsif ($childPid) {
		system ("cat $firstFile | $printCommand >>$errorRedirection 2>&1")
			and die "Error while running lpr: $!";
	} else {
		sleep ($timeBetween);
		system ("cat $secondFile | $printCommand >>$errorRedirection 2>&1")
			and die "Error while running lpr: $!";
		exit;
	}
}

##############################################################################

sub printDuplexCups ($$$) {

	my $printCommand = shift;
	my $file = shift;
	my $timeBetween = shift;

	if (!defined($childPid = fork())) {
		die "kann fork nicht ausfhren: $!";
	} elsif ($childPid) {
		$printCommand =~ s/oddeven/odd/;
		system ("cat $file | $printCommand >> $errorRedirection 2>&1")
			and die "Error while running lpr: $!";
	} else {
		$printCommand =~ s/oddeven/even/;
		sleep ($timeBetween);
		print "$printCommand \n";
		system ("cat $file | $printCommand >> $errorRedirection 2>&1")
			and die "Error while running lpr: $!";
		exit;
	}
}

##############################################################################


#
# Liest die Konfigurationsdatei ein

sub readConfig (@) {

	my @rcfiles = @_;
	my $rcfile;
	
	foreach $rcfile (@rcfiles) {

		next unless (-r $rcfile);
	
		open (RCFILE, $rcfile) || die "Could not open $rcfile: $!";

		while (<RCFILE>) {
			if (/^([^#=\s]+)=(["']?)(.*)\2\s+$/) { 
				$Config{$1} = $3; 
			}
		}
			
		close RCFILE || die "Could not close $rcfile: $!";
		
	}

	# Abwrtskompatiblitt
	$Config{CHARSET} = $Config{charset} if defined $Config{charset};
}

##############################################################################

sub readOpts () {

	# wird fr die Optionen bentigt (gehrt zum Standardumfang von Perl 5)
	use Getopt::Long; 
	Getopt::Long::Configure ("no_ignore_case");

	
	my %opt;									# Aufrufoptionen	
	my $error = 0;								# Beenden mit Fehler
	
	#
	# Optionen einlesen und der zugehrigen Variablen zuordnen
	
	GetOptions (
	
		'h|help' 				=> 	\$opt{help},
		'v|version'				=>	\$opt{version},

		'p|printer=s' 			=>	\$Config{PRINTER},
		'C|printcommand=s'		=>	\$Config{PRINT_COMMAND},
		'i|penguin=s'			=>	\$Config{PENGUIN},
		't|speed=i'				=>	\$Config{SPEED},
		'w|wait=i'				=>	\$Config{WAIT},
		'F|font=s'				=>	\$Config{FONT},
		'P|paper=s'				=>	\$Config{PAPER},
		'S|frontstyle=s'		=>	\$Config{FRONTSTYLE},
		'a|printed-headers=s'	=>	\$Config{PRINTED_HEADERS},
        'z|fontsize=s'          =>  \$Config{FONTSIZE},
        'W|wrapmargin=s'        =>  \$Config{WRAPMARGIN},
		'c|charset=s'			=>	\$Config{CHARSET},
		'D|debug!'				=>	\$Config{DEBUG},
		'foreground!'			=>	\$Config{FOREGRUND},
		'e|date=s'				=>	\$Config{DATE},
		'E|date-format=s'		=>	\$Config{DATE_FORMAT},
		'r|rcfile=s'			=>	\$Config{RCFILE},
		'A|addressformat=s'		=>	\$Config{ADDRESSFORMAT},
		'g|topmargin=s'			=>	\$Config{TOPMARGIN},
		'G|bottommargin=s'		=>	\$Config{BOTTOMMARGIN},
		'j|leftmargin=s'		=>	\$Config{LEFTMARGIN},
		'J|rightmargin=s'		=>	\$Config{RIGHTMARGIN},
		'n|verbatimnormal=s'	=>	\$Config{VERBATIMNORMAL},
		'V|verbatimsig=s'		=>	\$Config{VERBATIMSIG},
		'sig_regexp=s'			=>	\$Config{SIG_REGEXP},


		'l|lang=s'				=>	\$opt{LANG},
		'd|duplex!'				=>	\$opt{DUPLEX},
		'x|x-face!'				=>	\$opt{XFACE},
		'H|headrule!'			=>	\$Config{HEADRULE},
		'b|footrule!'			=>	\$Config{FOOTRULE},
		'1'						=> 	\$opt{paper1},
		'2'						=>	\$opt{paper2},
		's|rem_sig!'			=>	\$opt{REM_SIG},
		'q|rem_quote!'			=>	\$opt{REM_QUOTE},
		
		'f|file=s'				=>	\$opt{file},
		
	) or $error = 1;
	
	
	#
	# Logische Optionen => on/off
	
	foreach (qw /DUPLEX REM_SIG REM_QUOTE HEADRULE FOOTFULE XFACE/) {
		next unless defined $opt{$_};
		
		if ($opt{$_}) {
			$Config{$_} = "on";
		}
		else {
			$Config{$_} = "off";
		}	
	}
	
	#
	# Papiersparmodus
	
	$Config{'PAPERSAVE'} 	= "off"			if $opt{'paper1'};
	$Config{'PAPERSAVE'}	= "on"			if $opt{'paper2'};

	#
	# andere Sprache
	$Config{'LANG'} 		= $opt{'LANG'}	if defined $opt{'LANG'};

	# aus Datei lesen

	if (defined $opt{'file'}) {
		if ($opt{'file'} eq "-") {
			@ARGV = "-";
		}
		else {
			unless (-e $opt{'file'}) {		
				die "Could not open $opt{'file'}. Maybe the file does not exist.\n";
			}
			@ARGV = $opt{'file'};
		}			
	}
	else {
		@ARGV = "-";
	}
	
	
	# Rckgabe: Wahrheitswerte fr 
	# I Hilfe, II Version

	return ($opt{'help'}, $opt{'version'}, $error);

}

##############################################################################

sub getPaperConfig () {

	my $DebianPaper = "A4";
	my $paperFormat;
	my $Papersize = "/etc/papersize";

	return unless (-r $Papersize);

	open (RCFILE, $Papersize) or die "Could not open $Papersize: $!";
	chomp($DebianPaper = <RCFILE>);
	close RCFILE or die "Could not close $Papersize: $!";

	foreach ($DebianPaper) {
		/a4/i 		&& 	do { $DebianPaper = "A4";	 		last };
		/letter/i	&&	do { $DebianPaper = "letter";		last };
	}

	return $DebianPaper;
}

##############################################################################

sub createTemp () {
	#
	# temp directory / temp files
	$Temp{dir} = tempdir("muttprint-XXXXXX", TMPDIR => 1, CLEANUP => 1);
	$Temp{content} = "$Temp{dir}/content";
	$Temp{latex} = "$Temp{dir}/mail.tex";
	$Temp{logf} = "/tmp/muttprint.log";
	$Temp{dvi} = "$Temp{dir}/mail.dvi";
	$Temp{ps} = "$Temp{dir}/mail.ps";
	$Temp{psnew} = "$Temp{dir}/mail-new.ps";
	$Temp{ps1} = "$Temp{dir}/mail1.ps";
	$Temp{ps2} = "$Temp{dir}/mail2.ps";
	$Temp{xf_raw} = "$Temp{dir}/xface.raw";
	$Temp{xf_xbm} = "$Temp{dir}/xface.xbm";
	$Temp{xf_eps} = "$Temp{dir}/xface.eps";
}

##############################################################################

sub findCommonDir ($) {

	my $sort = shift;
	my $prefix = "";
	
	$prefix = $0 =~ m#(.*)/bin/muttprint#;
	
	foreach ($prefix, "/usr/", "/usr/local", $ENV{HOME}) {
		my $common_dir = "$_/$sort/muttprint/";
		if (-d $common_dir) {
			return $common_dir;
		}
	}
}

##############################################################################

sub changeForXface ($) {

	open (RAW, ">$Temp{'xf_raw'}") || die "Could not create XF-Raw file: $!";
	print RAW @_;
	close RAW;

	system ("uncompface -X $Temp{xf_raw} $Temp{xf_xbm}") 
		and die "Could not convert XF-Raw into XF-XBM: Maybe 'uncompface' not installed: $!";
	
	system ("convert $Temp{xf_xbm} $Temp{xf_eps}")
		and die "Could not convert XF-XBM into XF-EPS: Maybe 'convert' not installed: $!";
	
	$Config{'PENGUIN'} = $Temp{xf_eps};

	$image_height = "15mm";

}

##############################################################################

sub getCharset ($) {
	for (shift) {
		/iso[_\-]8859[_\-]15/i		&& return "latin9";
		/iso[_\-]8859[_\-]1/i 		&& return "latin1";
		/iso[_\-]8859[_\-]2/i 		&& return "latin2";
		/iso[_\-]8859[_\-]3/i		&& return "latin3";
		/iso[_\-]8859[_\-]4/i		&& return "latin4";
		/iso[_\-]8859[_\-]9/i		&& return "latin5";
		/(cp|windows)[_\-]?1252/i	&& return "latin1";
		/(cp|windows)[_\-]?1250/i	&& return "latin2";
		
		return "latin1";
	}
}
	
		
##############################################################################

sub createLatex () {

	my $PengCode = "";						# Kommando fr den Pinguin
	my $PengTab;			 				# restl. Gre fr Pinguin
	my $BeforeHeader;
	my $sansserif = '';
	my $AfterHeader;
	my $fontpackage = '';
	$fontpackage = $fontpackages{$Config{'FONT'}} if exists $fontpackages{$Config{'FONT'}};
	my $headerrule_other = '\\renewcommand{\\headrulewidth}{0pt}';
	my $headerrule_first = '\\renewcommand{\\headrulewidth}{0pt}';
	my $footerrule = "";
	my $charset = $Config{CHARSET};
	my $fontencString;
	my $isolatinextensions = getISOlatinExtensions($charset);

	# Sans-Serif-Verhalten
	if ($fontpackage =~ /-SANSSERIF-/) {
		$fontpackage =~ s/-SANSSERIF-//;
		$sansserif = '\renewcommand{\familydefault}{\sfdefault}';
	}

	my $LatexPackages = "$fontpackage,fancyhdr,lastpage";

	# Richtiges Tab-Verhalten
	foreach (qw/VERBATIMNORMAL VERBATIMSIG/) {
		$Config{$_} = 'obeytabs=true,' . $Config{$_};
	}

	# LaTeX Fontencoding
	$fontencString = defined $Config{TEX_FONTENC}
		? "\\usepackage[$Config{TEX_FONTENC}]{fontenc}"
		: "";

	if ($charset eq "latin9") {
		$charset = "latin1";
	}

	# Pinguin drucken?

	if ($Config{'PENGUIN'} ne "off") {
		$PengCode = <<"EOF";
\\raisebox{4mm}{
\\begin{minipage}[t]{20mm}
\\begin{flushright}
~ \\\\
\\includegraphics[height=$image_height]{$Config{'PENGUIN'}}
\\end{flushright}
\\end{minipage}}
EOF
		$PengTab = 158 - $Config{LEFTMARGIN} - $Config{RIGHTMARGIN};
	}
	else {
		$PengTab = 170 - $Config{LEFTMARGIN} - $Config{RIGHTMARGIN};
	}

	my $sig_tex = "";
	
	if (defined $signature) {
		$sig_tex = <<"EOF";
\\begin{Verbatim}[$Config{VERBATIMSIG}]
$signature
\\end{Verbatim}
EOF
	}

	if ($Config{PAPER} eq "letter") {
		$PengTab += 6;			# Letter ist breiter
	}

	$PengTab .= "mm";			# Maeinheit anhngen

	#
	# Frontstyle:
	for ($Config{'FRONTSTYLE'}) {
		/^plain$/i 			&& do {		
			$BeforeHeader = "";
			$AfterHeader = "\\vspace{8mm}";				
		last; };
			
		/^fbox$/i 			&& do {
			$BeforeHeader = '\\fbox{';
			$AfterHeader = '} \\vspace{5mm}';
		last; };
		/^shadowbox$/i		&& do {
			$LatexPackages .= ",fancybox";
			$BeforeHeader = '\\shadowbox{';
			$AfterHeader = '} \\vspace{3mm}';
		last; };
		/^(?-i:o)valbox$/i	&& do {
			$LatexPackages .= ",fancybox";
			$BeforeHeader = '\\ovalbox{';
			$AfterHeader = '} \\vspace{6mm}';
		last; };
		/^(?-i:O)valbox$/i	&& do {
			$LatexPackages .= ",fancybox";
			$BeforeHeader = '\\Ovalbox{';
			$AfterHeader = '} \\vspace{6mm}';
		last; };
		/^doublebox$/i		&& do {
			$LatexPackages .= ",fancybox";
			$BeforeHeader = '\\doublebox{';
			$AfterHeader = '} \\vspace{5mm}';
		last; };
		/^grey$/i			&& do {
			$LatexPackages .= ",color";
			$BeforeHeader = '\\colorbox[gray]{0.85}{';
			$AfterHeader = '} \\vspace{8mm}';
		last; };
		/^greybox$/i		&& do {
			$LatexPackages .= ",color";
			$BeforeHeader = '\\definecolor{light}{gray}{0.85} \\fcolorbox{black}{light}{';
			$AfterHeader = '} \\vspace{6mm}';
		last; };
	

			$BeforeHeader = "";
			$AfterHeader = '\\vspace{5mm} \\hrule \\vspace{5mm}';	
	}
	
	#
	# Headerrule
	if ($Config{'HEADRULE'} eq "on") {
		$headerrule_other = '\\renewcommand{\\headrulewidth}{0.5pt}';
	}
	
	#
	# Footerrule
	if ($Config{'FOOTRULE'} eq "on") {
		$footerrule = '\\renewcommand{\\footrulewidth}{0.5pt}';
	}
	
	
	# if there's no subject:
	$Header{'Subject'} ||= "(no subject)";

	# short Subject for head line
	$Header{'ShortSubject'} = $Header{'Subject'};
	my $numberReplacements = 0;
	
	# it's better to limit the number of substitutions to 10 because there
	# might be an error in my regexp and endless loops aren't very good :-)
	while (length($Header{ShortSubject}) > 60 && $numberReplacements < 10) {
		$Header{'ShortSubject'} =~ s/\s+\S+(\s+\\ldots)*(\s+\S+)$/ \\ldots$2/;
		$numberReplacements++;
	}

	open (LATEX, "> $Temp{'latex'}") || die "unable to create $Temp{'latex'}: $!";


#
# hier wird die eigentliche LaTeX-Quelldatei erzeugt


print LATEX <<EOF;
\\documentclass[compat2,$Config{FONTSIZE}]{article}
$fontencString
\\renewcommand{\\tt}{\\rm}
\\usepackage[$Config{LPack}]{babel}
\\usepackage[$charset]{inputenc}
\\usepackage{$LatexPackages}
\\usepackage[${paperformat}paper,left=$Config{LEFTMARGIN}mm,right=$Config{RIGHTMARGIN}mm,%
	top=$Config{TOPMARGIN}mm,bottom=$Config{BOTTOMMARGIN}mm,headsep=5mm]{geometry}
\\usepackage{fancyvrb,graphicx,marvosym,textcomp,array}
$sansserif
\\setlength{\\parindent}{0mm}
$isolatinextensions
\\pagestyle{fancy}
\\lhead{\\itshape $Header{'ShortFrom'}}
\\rhead{\\bfseries $Header{'ShortSubject'}}
\\cfoot{}
\\lfoot{\\today}
\\rfoot{$String{'Page'} \\thepage\\ $String{'of'} \\pageref{LastPage}}
$headerrule_other
$footerrule
\\fancypagestyle{plain}{%
$headerrule_first
\\fancyhf{} 
\\lfoot{\\today}
\\setlength{\\headsep}{0mm}
\\setlength{\\headheight}{0mm}
\\addtolength{\\footskip}{12pt}
\\addtolength{\\footskip}{5mm}
\\rfoot{$String{'Page'} \\thepage\\ $String{'of'} \\pageref{LastPage}}}
$Config{LATEXCODE}
$Config{LATEXCODE1}
$Config{LATEXCODE2}
$Config{LATEXCODE3}
$Config{LATEXCODE4}
$Config{LATEXCODE5}
\\begin{document}
\\thispagestyle{plain}
$BeforeHeader
{\\large
\\begin{tabular}[t]{\@{}r>{\\raggedright}p{$PengTab}\@{}p{0mm}\@{}}
@PrintedMailheaders
\\end{tabular}}
\\hfill
$PengCode
$AfterHeader
\\VerbatimInput[$Config{VERBATIMNORMAL}]{$Temp{content}}
\\setlength{\\parskip}{-7mm}
$sig_tex
\\end{document}
EOF

	close LATEX;

}

##############################################################################

sub getISOlatinExtensions ($) {
	my %Extensions;
	
	$Extensions{latin159} = <<'EOF';
\DeclareInputText{165}{\textyen}
\DeclareInputText{173}{-}
\DeclareInputText{172}{\textlnot}
\DeclareInputText{174}{\textregistered}
\DeclareInputText{176}{\textdegree}
\DeclareInputText{177}{\textpm}
\DeclareInputText{178}{\texttwosuperior}
\DeclareInputText{179}{\textthreesuperior}
\DeclareInputText{181}{\textmu}
\DeclareInputText{185}{\textonesuperior}
\DeclareInputText{215}{\texttimes}
\DeclareInputText{247}{\textdiv}
EOF

	$Extensions{latin9} = <<'EOF';
\DeclareInputText{164}{\EURcr}
\DeclareInputText{180}{\v{Z}}
\DeclareInputText{166}{\v{S}}
\DeclareInputText{168}{\v{s}}
\DeclareInputText{184}{\v{z}}
\DeclareInputText{188}{\OE}
\DeclareInputText{189}{\oe}
\DeclareInputText{190}{\"{Y}}
EOF
	
	$Extensions{latin2} = <<'EOF';
\DeclareInputText{173}{-}
\DeclareInputText{176}{\textdegree}
\DeclareInputText{215}{\texttimes}
\DeclareInputText{247}{\textdiv}
EOF
	
	$Extensions{latin3} = <<'EOF';
\DeclareInputText{173}{-}
\DeclareInputText{176}{\textdegree}
\DeclareInputText{177}{\textpm}
\DeclareInputText{178}{\texttwosuperior}
\DeclareInputText{179}{\textthreesuperior}
\DeclareInputText{181}{\textmu}
\DeclareInputText{185}{\textonesuperior}
\DeclareInputText{215}{\texttimes}
\DeclareInputText{247}{\textdiv}
EOF

	$Extensions{latin4} = <<'EOF';
\DeclareInputText{173}{-}
\DeclareInputText{176}{\textdegree}
\DeclareInputText{215}{\texttimes}
\DeclareInputText{247}{\textdiv}
EOF

	$Extensions{cp1252} = <<'EOF';
\DeclareInputText{128}{\EURcr}
\DeclareInputText{130}{\quotesinglbase}
\DeclareInputText{131}{\textflorin}
\DeclareInputText{132}{\quotedblbase}
\DeclareInputText{133}{\dots}
\DeclareInputText{134}{\dag}
\DeclareInputText{135}{\ddag}
\DeclareInputText{136}{\^{}}
\DeclareInputText{137}{\textperthousand}
\DeclareInputText{138}{\v S}
\DeclareInputText{139}{\guilsinglleft}
\DeclareInputText{140}{\OE}
\DeclareInputText{142}{\v Z}
\DeclareInputText{145}{\textquoteleft}
\DeclareInputText{146}{\textquoteright}
\DeclareInputText{147}{\textquotedblleft}
\DeclareInputText{148}{\textquotedblright}
\DeclareInputText{149}{\textbullet}
\DeclareInputText{150}{\textendash}
\DeclareInputText{151}{\textemdash}
\DeclareInputText{152}{\~{}}
\DeclareInputText{153}{\texttrademark}
\DeclareInputText{154}{\v s}
\DeclareInputText{155}{\guilsinglright}
\DeclareInputText{156}{\oe}
\DeclareInputText{158}{\v z}
\DeclareInputText{159}{\"Y}
EOF
	
	$Extensions{cp1250} = <<'EOF';
\DeclareInputText{128}{\EURcr}
\DeclareInputText{130}{\quotesinglbase}
\DeclareInputText{132}{\quotedblbase}
\DeclareInputText{133}{\dots}
\DeclareInputText{134}{\dag}
\DeclareInputText{135}{\ddag}
\DeclareInputText{137}{\textperthousand}
\DeclareInputText{138}{\v S}
\DeclareInputText{139}{\guilsinglleft}
\DeclareInputText{140}{\@tabacckludge'S}
\DeclareInputText{141}{\v T}
\DeclareInputText{142}{\v Z}
\DeclareInputText{143}{\@tabacckludge'Z}
\DeclareInputText{145}{\textquoteleft}
\DeclareInputText{146}{\textquoteright}
\DeclareInputText{147}{\textquotedblleft}
\DeclareInputText{148}{\textquotedblright}
\DeclareInputText{149}{\textbullet}
\DeclareInputText{150}{\textendash}
\DeclareInputText{151}{\textemdash}
\DeclareInputText{153}{\texttrademark}
\DeclareInputText{154}{\v s}
\DeclareInputText{155}{\guilsinglright}
\DeclareInputText{156}{\@tabacckludge's}
\DeclareInputText{157}{\v t} 
\DeclareInputText{158}{\v z}
\DeclareInputText{159}{\@tabacckludge'z}
EOF

	for (shift) {
		/latin[15]/ 	&& return join("", @Extensions{qw/latin159 cp1252/});
		/latin9/		&& return join("", @Extensions{qw/latin159 cp1252 latin9/});
		/latin2/ 		&& return join("", @Extensions{qw/latin2 cp1250/});
		/latin3/ 		&& return $Extensions{latin3};
		/latin4/ 		&& return $Extensions{latin4};
		return "";
	}
} 

###################################################################################

sub getShortFrom ($$) {
	my $Header;
	my $kind_of_Header;
	my $Realname;
	
	if ($Header = shift) {
		$kind_of_Header = $String{'From'};		
	} 
	elsif ($Header = shift) {
		$kind_of_Header = $String{'To'};
	}
	else {
		return ""; 
	}

	$Realname = getRealname($Header);
	
	if ($Realname) {
		return "$kind_of_Header $Realname";
	}
	else {
		my $retVal = (split /,\s/, $Header)[0];
		$retVal =~ s/_/\\_/g;
		$retVal =~ s/-/{-}/g;
		return "$kind_of_Header $retVal";
	}
}
	

sub getRealname ($) {
	my $Header = shift;
	
	for ($Header) {

		if (/^\s*['"]*(.+?)["']*\s*<.+\@.+>/ || /^.+\@.+ \((.+)\)$/) {
			return $1;
		}

		return undef;
	}
}


##############################################################################

sub getNumberOfPages ($) {
	my $auxfile = shift;
	my $numberOfPages = 0;

	open (AUX, "$auxfile") or die "Could not open $auxfile: $!";
	
	while (<AUX>) {
		($numberOfPages) = /\\newlabel{LastPage}{{}{(\d+)}}/;
	}
	
	close AUX or die "Could not close $auxfile: $!";
	
	return $numberOfPages;
}

##############################################################################


#
# Here we decode HEADER
# This is useful for printing raw mails / usenet articles
# See RFC 2047 for MIME encoding. I would not say that this code decodes
# all correct, but when I tested it, it worked :)
#
# Tipp:
# For printing with KNode (KDE newsreader) save the article to a file and
# execute   muttprint -f /tmp/some_file.txt
# [This decoding stuff was done for KNode ;)]

sub decodeHeader () {
	
	my $EncPart;
	
	foreach $EncPart ($_ =~ /=\?ISO-8859-[0-9]+\?Q\?(.*?)\?=/gi) {		
		
 		$EncPart =~ s/=([0-9A-Fa-f]{2})/chr(hex($1))/eg;
 		$EncPart =~ s/_/ /g;
		
		s/=\?ISO-8859-[0-9]+\?Q\?.*?\?=/$EncPart/i;
		
	}
}

##############################################################################




#
# Because lots of mail clients do not break the lines, we must do it here.
# This is some like 'fmt', but better for our needs. We do not use 'fmt',
# because its -s Option is *not* available on all systems!

sub writeFormated ($*$) {

	local $_ = shift;
	my $fh = shift;
	my $wrapmargin = shift;
	
	$^L = "";
	my $oldfh = select $fh;
	$~ = "CONTENT";

	#
	# only wrap if 20 < $wrapmargin < 120
	if ($wrapmargin > 120 || $wrapmargin < 20) {
		print;
		return;
	}
	
	eval("format CONTENT = \n^" . '<' x ($wrapmargin - 1) . " ~~ \n\$_\n.");

	#
	# at first, we split each paragraph
	
	for (split /(?:\s*\n\s*){2,}/) {
	
		#
		# then, we look if *every* line is too long
		if ((() = /^.{$wrapmargin,}$/gmo) == tr/\n//) {
		
			#
			# if so, we fill it! (as a normal fmt does)
			
			s/\s*\n\s*/ /g;
			write;
		} 
		else {
		
			#
			# and if not, we break every line separately
			# (as fmt -s does)
			
			for (split /\n/) {
				
				if (/^.{$wrapmargin,}$/o) {
					write;
				} 
				else {
					print $_, "\n";
				}
			
			}
		}
		
		#
		# finally, we print a Newline on the end of each
		# paragraph
		
		print "\n";		
	}
	
	$| = 1;
	select $oldfh;
}

# .. so this is some like 'fmt' and 'fmt -s' in one

##############################################################################

sub copyFile ($$) {
	my $src = shift;
	my $dst = shift;

	open (SRC, "<$src") or die "Could not open $src for reading: $!";
	open (DST, ">$dst") or die "Could not open $dst for writing: $!";

	while (<SRC>) {
		print DST $_;
	}

	close DST or die "Could not close $dst: $!";
	close SRC or die "Could not close $src: $!";
}


##############################################################################

sub convertDate ($) {
	my $date = shift;

	#
	# berprfen, ob das Modul installiert ist. Wenn nicht, Warnung
	# ausgeben und so verwenden.
	eval "use Date::Parse";
	
	if ($@) {
		warn "It seems that you don't have installed ".
			"the module \"Date::Parse\" on your system. Please install it or ".
			"use the setting \"DATE=original\" in your ~/.muttprintrc.\n";
		return $date;
	}
	
	return strftime($Config{DATE_FORMAT}, localtime(str2time($date)));

}

sub modifyPS ($) {

	my $Tumble;
	my $Postscript;
	my $DuplexCommand;
	
	# 
	# /Tumble true will use a short edge binding while false will use a long
	# ledge binding.
	# long edge binding makes a duplex printing looks right for portrait page.
	# short edge binding makes a duplex printing looks right for landscape
	# page.
	#

	
	if ($_[0] eq "portrait") {
		$Tumble = "false";	
	}
	elsif ($_[0] eq "landscape") {
		$Tumble = "true";
	}
	
	$DuplexCommand = <<EOF;
%%BeginFeature: *Duplex DuplexTumble

    2 dict dup /Duplex true put dup /Tumble $Tumble  put setpagedevice

%%EndFeature
EOF
	
	
	open(READ_PSFILE, "$Temp{'ps'}") || die "$!";
	$Postscript = join("", (<READ_PSFILE>));	
	close READ_PSFILE;
	
	#
	# notwendige Kommentare hinzufgen!
	
	$Postscript =~ s#\%\%EndComments#$DuplexCommand#;
	
  	open(WRITE_PSFILE, "> $Temp{'ps'}") || die "$!";
	print WRITE_PSFILE $Postscript;
	close WRITE_PSFILE;

}

##############################################################################

sub getDefaultPrinterCDE () {

	my $configfile = "$ENV{HOME}/.printers";
	my $printer;
	
	return "" unless (-r $configfile);

	open (CDEPRINTER, $configfile) 
		or die "Could not open CDE printer configuration file: $!";
	
	while (<CDEPRINTER>) {
		last if (($printer) = /^_default\s+(\w*)/);
	}

	close CDEPRINTER or die "Could not close CDE printer configuration file: $!";
	return $printer if defined $printer;
}


##############################################################################


sub setStrings ($) {

	my $stringsAreSet = FALSE;
	my $lang = shift;
	my $sharedir = findCommonDir('share');
	my $libdir = findCommonDir('lib');
	my (@translationDirs) = ("$sharedir/translations", $sharedir,
			"$libdir/translations", $libdir);
	
	if ($lang =~ /^(\w{2})/i) {
		my $shortLang = $1;

		foreach (@translationDirs) {
			if (-r "$_/translation-$1.pl") {
				do("$_/translation-$1.pl"); 
				$stringsAreSet = TRUE;
			}
		}
	}

	unless ($stringsAreSet) {

$String{"Benutzung"} = <<EOF;

Usage:   muttprint [option]... [-f file]
 
Options:

PLEASE NOTICE: These options override the corresponding settings in 
~/.muttprintrc and /etc/Muttprintrc.

-h, --help
       This help.

-v, --version
       Prints the current version of Muttprint.

-f [file], --file [file]
       Reads from file instad of STDIN.

-p [printername], --printer [printername]
       Uses a specific printer.
       "-" stands for STDOUT
       For printing to a file use TO_FILE:/path/to/file

-C [print command], --printcommand [print command]
       Sets the printing command. "\$PRINTER" is substituted by the
       printer name.
       CUPS support is turned on by "CUPS" (or set it to any command
       which containes the string "\$CUPS_OPTIONS").

-i [file], --penguin [file]
       Sets the picture printed on the first page.

-x, --x-face | -nox, --nox-face
       Turn printing of X-Faces on/off.

-t [number], --speed [number]
       Time in seconds which the printer needs for one page.
		   
-w [number], --wait [number]
       Time between printing odd and even pages for duplex printing.

-F [fontname], --font [fontname]
       Font family for printing. Possible values are:
       Latex, Latex-bright, Times, Utopia, Palatino, Charter and Bookman
	   
-H, --headrule | -noH, --noheadrule
       Turn printing of the headrule on or off.
	   
-b, --footrule | -nob, --nofootrule
       Turn printing of the footrule on or off.
	   
-S Style | --frontstyle Style
       Choose a style for the headers on the first page:
       plain, border (default), fbox, shadowbox, ovalbox, Ovalbox, doublebox,
       grey, greybox. 
       Read the manual for a detailed description of this values.

-a [headers], --printed-headers [headers]
       Headers that should be printed. See manpage/manual for details.
       Example: /Date/_To_From_*Subject*

-P [paperformat], --paper [paperformat]
       Paper format: "letter" (US) or "A4" (Europe).

-l [language], --lang [language]
       Language for messages and printing.

-c [charset], --charset [charset]
       Input charset: latin1, latin2, latin3, latin4, latin5, latin9, koi8-r
       utf8, auto (read the manual before you use "auto" or "utf8").

-e [string], --date [string]
       original: prints the date as it is in the header
       local:    converts to local time zone and language

-E [string], --date-format [string]
       date format string; see strftime(3) for details

-A [string], --addressformat [string]
       Specifies the format of the mail address in the header,
       see manpage or documentation for details.

-n [string], --verbatimnormal [string]
       Is used for setting the formating of the normal mail text. Read
       the user's guide and the manpage for details.

-V [string], --verbatimsig [string]
       Same as --verabtimnormal, but this sets the formating
       of the signature.

-D, --debug | -noD, --nodebug
       Writes useful information to a logfile /tmp/muttprint.log.

-d, --duplex | -nod, --noduplex
       Enables or disables duplex printing.

-g [number], --topmargin [number]
       Top margin in millimeter

-G [number], --bottommargin [number]
       Bottom margin in millimeter

-j [number], --leftmargin [number]
       Left margin in millimeter

-J [number], --rightmargin [number]
       Right margin in millimeter

-2 | -1
       Prints two pages on one sheet. Corresponds to "papersave mode".

-s, --rem_sig | -nos, --norem_sig
       Removes the signature (separated by "-- ") in the printing.

--sig_regexp [Regular expression]
       Specifies the regular expression used to recognize the signature.

-q, --rem_quote | -noq, --norem_quote
       Remove the quoted paragraph from the printing.

-z [size], --fontsize [size]
       Font size: 10pt, 11pt, 12pt (only this values)

-W [number], --wrapmargin [number]
       Specifies how long lines could be.
	   
-r [file], --rcfile [file]
       Specifies a additional configuration file.

EOF

$String{"Lizenz"} = "This program is distributed under the terms of the
GPL and can be freely copied.
";

$String{"Bugs"} = "Please report bugs to <Bernhard.Walle\@gmx.de>.\n";

$String{"FileNotFound"} = "The specified file was not found.\n";

@String{"From", "To", "Subject", "CC", "Date", "Page", "of", "Newsgroups", "Organization"} =
("From:", "To:", "Subject:", "Carbon Copy:", "Date:", "page", "of", "Newsgroups:", "Organization:");

}

# Rckwrtskompatiblitt
# wird irgendwann entfernt!!
$Config{'NEWSGROUPS_STRING'} = $Config{'NEWSGROUP_STRING'} 
			if defined $Config{'NEWSGROUP_STRING'};

	foreach ("From", "To", "Subject", "CC", "Date", "Page", "of", "Newsgroups", "Organization") {
		$String{$_}	= $Config{"\U$_"."_STRING"} if defined $Config{"\U$_"."_STRING"};
	}
}

__END__

#######################################################################################
# vim:sw=4 ts=4
