#!/usr/bin/perl
#
# Datumsberechnung fr Contesttermine (z.B. DF7RX-Datenbank)
#
# Der Aufruf kann mit folgenden Optionen erfolgen:
#
# contest.pl <Jahresangabe>    Hierbei wird ggf. 1900 oder
#                              2000 dazugezhlt. Zahlen kleiner
#                              gleich 12 bedeuten aber Monate.
# contest.pl <Monatsangabe>    Ein Monat zweischen 1..12 oder eine
#                              abgekrzte Form aus drei Buchstaben,
#                              also JAN, FEB, MAR usw.
#
# contest.pl <Monat>/<Jahr>    Monat und Jahresangabe mit
#                              Schrgstrich getrennt.
#
# contest.pl <name>            Ausgabe der Datei <name>.txt,
#                              wobei das symbolische Datum (Tag) durch
#                              das Datum des laufenden Jahres
#                              ersetzt wird, an dem der Contest
#                              stattfindet. 
#
# Das Programm formt alle in der Eingabedatei vorhandenen Tags in
# feste Datumsangaben um. Das Ergebnis wird nach STDOUT geschrieben.
# Tags sind Terminangaben nach folgendem Schema (in spitzen Klammern):
#
# Klasse 1: Feststehende Termine
# 0305      = 3. Mai (festes Datum)
#
# Klasse 2: Variable Termine.
# Hier kann man entweder einen Wochentag angeben (MON, TUE, WED...).
#
# Beispiele:
# 03SUN03   = 3. Sonntag im Mrz
# 03SAT03+1 = Samstag des 3. vollen Wochenendes
# 03SAT03+1 = Sonntag des 3. vollen Wochenendes
# LASUN05   = Letzter Sonntag im Mai
# LASUN05-1 = Samstag des letzten vollen Wochenendes im Mai
#
# Klasse 3: Von Ostern abhngige Termine
#
# Beispiele:
# EASTER-43 = 43 Tage vor Ostersonntag
# EASTER    = Ostersonntag
# EASTER1   = Ostermontag
#
# Bu- und Bettag ist der Mittwoch vor dem 4. Sonntag im November
# Pfingstmontag ist der 50. Tag nach Ostersonntag.
#
# Als zweites Feld im Tag ist die Anfangszeit in Stunden+Minuten
# anzugeben, also 1000 fr 10 Uhr UTC.
#
# Als drittes Feld folgt die Dauer des Wettbewerbs in Minuten.
# Aus dieser Angabe wird die Endzeit berechnet, da diese ja ggf.
# ber eine Monatsgrenze hinausgehen knnte.
#
# Als viertes Feld kann ein Kommentar angegeben werden, der hinter
# dem Namen des Contests ausgegeben wird, z.B. um aus einem Regelfile
# alle drei Betriebsarten SSB, CW und RTTY abzuleiten. Bei den
# verschiedenen Terminen erscheint dann z.B:
#
#     CQ WW DX Contest SSB
#     CQ WW DX Contest CW
#     CQ WW DX Contest RTTY
#
# Dieses Feld mu nicht angegeben werden, falls es fehlt wird hier einfach
# ein Leerstring ausgegeben.
#
# Typische Tags:
#
# {LASUN12:1000:60}                 Letzter Sonntag im Dezember, 
#                                   10 Uhr, Dauer: 1 Stunde
# {02SAT02:0000:2880}               2. Samstag im Februar, 0 Uhr
#                                   Dater 48 Stunden
#
#
# Die Software erkennt automatisch, in welcher Umgebung sie
# aufgerufen wurde und ob sie HTML-Code oder normalen ASCII-Code
# erzeugen soll. Als CGI-Skript gerufen erfolgt die bergabe
# der Parameter ber die ENV-Variable $QUERY_STRING. Ist diese
# also besetzt, wird automatisch HTML-Code erzeugt.
#
#
# Wnsche oder Probleme:
#
# 1. Es wre gut, wenn man statt 1/98 auch "1 98" schreiben knnte,
#    und auch "jan 1998" und auch vielleicht bei der Regelausgabe
#    das Jahr mit angeben knnte, soda man gleich den korrekten
#    Output fr das nchste Jahr drinstehen hat, also z.B.
#    "wpxrtty 1999"
#
# 2. Offline-HTML-Modus: DF7RX will offline HTML-Output
#    erzeugen - wie kann man das machen? Evtl. Command Line Switch?
# 
# Stand: 5.1.2000, DL6RAI

require "timelocal.pl";

$ENV{TZ} = "GMT";
$index = "index"; # nicht index.txt nennen!!
$comment = "";

$debug = 0;

@lit_wday[0..6] = ("sun","mon","tue","wed","thu","fri","sat");
@lit_month[1..12] = ("January","February","March","April","May","June",
			"July","August","September","October",
			"November","December");

chop($dir = `dirname $0`);
$dir .= "/contest_data";


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

#
# Wenn kein Argument gefunden wurde, versuche es erstmal
# ber $QUERY_STRING im Fall, wenn contest.pl als 
# CGI-Skript aufgerufen wurde.
#


$string = $ENV{'QUERY_STRING'};
$string =~ s/\%24/\$/g;
if ( length($string) > 0 ) {

	$type = "cgi";
	
	@vec = split (/\&/,$string);
	foreach $i (@vec) {
		$i =~ s/^/\$/;
		$i =~ s/=/=\"/;
		$i =~ s/$/\"/;
		$i =~ s/%3D/=/;
        	eval $i;
	}
} else {
	$type = "asc";
	$arg = $ARGV[$#ARGV];	# nur das letzte Argument auswerten
	$arg =~ tr/A-Z/a-z/;
	chomp($arg);
}

$job = "error_message";

if ($arg eq "") {

	chop($year = `date '+%Y'`);
	chop($s_mon = `date '+%m'`);
	$job = "display_timetable";

} elsif ($arg =~ /^[0-9]*$/) {

	if ( $arg > 12 ) {
		$year = $arg;
		$year += 1900 if ( $year >= 70 && $year <=99 );
		$year += 2000 if ( $year < 70 );
		$job = "display_timetable";
	} else {
		$s_mon = $arg;
		chop($year = `date '+%Y'`);
		$job = "display_timetable";
	}

} elsif ($arg =~ /^[0-9\/]*$/) {

	($s_mon,$year) = split(/\//,$arg);
	$year += 1900 if ( $year >= 70 && $year <=99 );
	$year += 2000 if ( $year < 70 );
	$job = "display_timetable";

} elsif ( -e "$dir/$arg.txt" ) {

	chop($year = `date '+%Y'`);
	$job = "display_rules";

} elsif ( $arg =~ /\*/ ) {

	$job = "display_wildcard";
	$pattern = $arg;
	$pattern =~ s/\*/\.\*/g;
	chop($year = `date '+%Y'`);

} elsif ( length($arg) == 3 ) {

	for $i (1..12) {

		if ( substr($lit_month[$i],0,3) =~ /$arg/i ) {

			$s_mon = $i;
			chop($year = `date '+%Y'`);
			$job = "display_timetable";
			last;
		}
	}
} 

@days[1..12] = (31,28,31,30,31,30,31,31,30,31,30,31) ;
$leap_day = 0;
if ( $year % 4 == 0 ) { $leap_day = 1; }
if ( $year % 100 == 0 ) { $leap_day = 0; }
if ( $year % 400 == 0 ) { $leap_day = 1; }
$days[2] = $days[2] + $leap_day;

$offset[0] = 0;
for $i (1..12) { $offset[$i] = $offset[$i-1] + $days[$i-1] }
	
#
# $d_min und $d_max stellen ein Zeitintervall dar, in das
# der berechnete Termin fallen mu, damit er ausgegeben
# wird.
#

$d_min = 0;
$d_max = 2**31;

if ( $s_mon != 0 ) {
	$d_min = timegm(0,0,0,1,$s_mon-1,$year % 100);
	$d_max = timegm(59,59,23,$days[$s_mon],$s_mon-1,$year % 100);
}

exit &$job();




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

sub error_message {

if ($type eq "asc") {
print <<NNNN;

Usage:       show/contest year
             show/contest month
             show/contest month/year
             show/contest *wildcard*
             show/contest rules-file

Example:     show/contest 1/97           - Table for January 1997
             show/contest feb            - Table for February
             show/contest wae            - Rules for WAE DX Contest
             show/contest *rtty*         - List all RTTY Contests

NNNN

} else {

	print <<NNNN;
Content-type: text/html

<html>
<h1>BCC Contest Database</h2>
<hr>
This is DL1HCM's (formerly DF7RX) very complete collection of Contest Rules
automatically calculating dates and times for over 300
different contests. You may search by year, month and name (including 
wildcard expression).
<hr>
<h2>Wildcard Expression Search</h2>
If you are looking for a contest starting with "Cal", enter <tt>Cal*</tt> in
the input field.
<form method=GET action="/cgi-bin/contest.pl">
   Name to search: <input type=text name=arg size=24 maxlength=24>
   <input type=submit name="GO">
</form>
<h2>Contest Calendar $year</h2>

NNNN

chop($year = `date '+%Y'`);
chop($s_mon = `date '+%m'`);

print "<center><table cellpadding=10 border=1>\n";
print "<tr><td align=center colspan=3><a href=/cgi-bin/contest.pl?arg=$year>All Contests in $year</a></tr>\n";
for $j (0..3) {
print "<tr>\n";
for $k (1..3) {
        $n=$j*3+$k;
	print "<td align=center><a href=/cgi-bin/contest.pl?arg=$n/$year>$lit_month[$n]</a>\n";
}
print "</tr>\n";
}
print "</table></center>\n";

print "<h2>Contest Calendar - past and future years</h2>";
print "<center><table cellpadding=5 border=1 width=100%>\n";
for $i ($year-5..$year+5) {
        next if ($i == $year);
	printf"<tr><th><a href=/cgi-bin/contest.pl?arg=$i>$i</a>\n";
	for $j (1..12) {
            printf"<td align=center><a href=/cgi-bin/contest.pl?arg=%s/%s>%s</a>\n",$j,$i,substr($lit_month[$j],0,3);
	}
        print"</tr>\n";
}
print "</table></center>\n";


}

}

sub display_rules {

	&chk_index;

	if ( $type eq "cgi" ) {
		print "Content-type: text/plain\n\n";
	}

	open(IN,"< $dir/$arg.txt") || die "Cannot open file $arg.txt\n";

	$title = "Contest Rules for $arg";

	while(<IN>) {
		chomp;
		tr /\015//d; # remove CR's
		if ( $type eq "cgi" ) {
			s//&auml/g;
			s//&ouml/g;
			s//&uuml/g;
			s//&Auml/g;
			s//&Ouml/g;
			s//&Uuml/g;
			s//&szlig/g;
		} else {
			s//ae/g;
			s//oe/g;
			s//ue/g;
			s//Ae/g;
			s//Oe/g;
			s//Ue/g;
			s//ss/g;
		}
		next if /^#/;
		if ( /^\{.*\}/ ) {
			# Die Symbole sind durch { und } gekennzeichnet.
			@word = split/[ \t]+/;
			($a,$e) = &process_symbol($word[0]);
			$dates = &ptime($a,$e,"l");
			print "$dates\n";
		} else {
			print "$_\n";
		}
	}
	close(IN);
}

sub process_symbol {

	local($symbol) = $_[0];

	$symbol =~ s/[{} ]//g;
	
	# In den Symbolen steckt das symbolische Datum, Startzeit
	# und Dauer in Minuten

	($symdate,$bg_time,$duration,$comment) = split(/:/,$symbol,4);
	$symdate =~ tr/A-Z/a-z/;
	if ($symdate =~ /\?/) { 
		($a,$e) = (-1,-1); 
	} else {
		($a,$e) = &calcdate($symdate,$bg_time,$duration);
	}

	return($a,$e);
}

sub display_timetable {

	&chk_index;

	if (! defined($s_mon)) {
		$title = "Contest Time Table for $year";
	} else {
		$title = "Contest Time Table for $lit_month[$s_mon] $year";
	}

	open(IN,"< $dir/$index") || die "Cannot open file $dir/$index\n";
	while (<IN>) {
		chop;
		next if /^#/;
		if ( /^\{.*\}/ ) { 

			# Die Symbole sind durch { und } gekennzeichnet.

			@word = split/[ \t]+/;

			($a,$e) = &process_symbol($word[0]);

			$dates = &ptime($a,$e,"s");

                        # Das ist der Rest der Zeile bis auf das letzte Wort

			$name = "";
			for ($i=1;$i<$#word;$i++) {
				$name .= sprintf("%s ",$word[$i]);
			}
			$name .= $comment;

                        # Hier steht der Dateiname, wo die Regeln drin sind

			$fname = $word[$#word];
			if ( ! -e "$dir/$fname" ) {
				$fname .= "\?\?\?";
			}
			$symb_fname = substr($fname,0,-4);

                        # Ausgabeformat
                        # in $a steht das Startdatum in Sekunden nach 
			# dem 1.1.1970 drin damit man es sortieren kann.

			$out = sprintf("%d|%s|%s|%s",$a,$dates,
				$name,$symb_fname);

                        # Und jetzt erstmal aufheben in den 
			# groen Sammelvektor @all

			push(@all,$out);
		}
	}

	&print_list;

	close(IN);
}

sub display_wildcard {

	&chk_index;

	$title = "Contest like $arg for $year";

	open(IN,"< $dir/$index") || die "Cannot open file $dir/$index\n";
	while (<IN>) {
		chop;
		next if /^#/;
		if ( /^\{.*\}/ ) { 

			# Die Symbole sind durch { und } gekennzeichnet.

			@word = split/[ \t]+/;

			($a,$e) = &process_symbol($word[0]);

			$dates = &ptime($a,$e,"s");

                        # Das ist der Rest der Zeile bis auf das letzte Wort

			$name = "";
			for ($i=1;$i<$#word;$i++) {
				$name .= sprintf("%s ",$word[$i]);
			}
			$name .= $comment;

			next unless ($name =~ /$pattern/i) ;

                        # Hier steht der Dateiname, wo die Regeln drin sind
			$fname = $word[$#word];
			if ( ! -e "$dir/$fname" ) {
				$fname .= "\?\?\?";
			}
			$symb_fname = substr($fname,0,-4);

                        # Ausgabeformat
                        # in $a steht das Startdatum in Sekunden nach 
			# dem 1.1.1970 drin damit man es sortieren kann.

			$out = sprintf("%d|%s|%s|%s",$a,$dates,
				$name,$symb_fname);

                        # Und jetzt erstmal aufheben in den 
			# groen Sammelvektor @all

			push(@all,$out);
		}
	}

	&print_list;

	close(IN);
}

sub print_list {

	if ( $type eq "cgi" ) {
		print "Content-type: text/html\n\n";
		print "<html>\n";
	}

	if ($#all == -1) {
		print "$title: Nothing found.\n";
		exit;
	}

	if ( $type eq "asc" ) {
		print "$title\n";
		print "=" x length($title),"\n\n";
		print " Date      Time      Contest               ";
		print "                         Rules File\n";
		print "-" x 78,"\n";
	}

	if ( $type eq "cgi" ) {

		if ($debug) {
		        print "ENV: $ENV{'QUERY_STRING'} <p>\n";
			print "String=$string <p>\n";
		}

		print "<h1>$title</h1>\n";
		print "<table cellpadding=5 border=1>\n";
		printf("<tr><th>Date<th>UTC<th>Name<th>Reference</tr>\n");
	}

	foreach (sort numerically @all) {
		($a,$dates,$name,$symb_fname) = split (/\|/,$_,4);

		# Wenn $a in das Zeitintervall ($d_min,$d_max) fllt, dann ausgeben.
		if ( $a >= $d_min && $a <=$d_max ) {
			if ($type eq "asc") {
				printf("%20s %-47s[%s]\n",$dates,$name,$symb_fname);
			}
			if ($type eq "cgi" ) {
				$hours = substr($dates,-9,9);
				$dates = substr($dates,0,length($dates)-10);
				printf("<tr><td>%s<td>%s<td>%-45s<td><a href=contest.pl?arg=%s>%s</a></tr>\n",
					$dates,$hours,$name,$symb_fname,$symb_fname);
			}
		}
	}

	if ($type eq "cgi" ) {
		print("</table>\n");
		print("</html>\n");
	}

	if ($type eq "asc" ) {
		print "-" x 78,"\n";
	}
}

sub numerically { $a <=> $b; }

sub ptime {

        #
        # Formatiertes Ausgeben von Start und Enddatum
        #
	local($a,$e,$form) = @_;
	local(@a,@e,$dates);


        # $a[0] = Sekunden
        # $a[1] = Minuten
        # $a[2] = Stunden
        # $a[3] = Tag des Monats
        # $a[4] = Monat, numerisch, Januar=0
        # $a[5] = Jahr, zweistellig
        # $a[6] = Wochentag
        # $a[7] = Tag des Jahres, 1. Januar = 1
        # $a[8] = Flag, ob Sommerzeit oder nicht
        
        
	@a = gmtime($a);
	@e = gmtime($e);
	@e2 = gmtime($e-1);
	$now = time();

	if ( $e2[0] eq 59 && $e2[1] eq 59 && $e2[2] eq 23 ) {
		@e = @e2;
		$e[0] = 0;
		$e[1] = 0;
		$e[2] += 1;
	}

	if ($form eq "s") {
		#
		# Kurzversion der Datumsausgabe
		#
		if ( $a[3] != $e[3] ) {
			$dates = sprintf("%-3s %2d-%2d %02d%02d-%02d%02d",
			substr($lit_month[$a[4]+1],0,3),
				$a[3],$e[3],$a[2],$a[1],$e[2],$e[1]);
		} else {
			$dates = sprintf("%-3s %2d    %02d%02d-%02d%02d",
			substr($lit_month[$a[4]+1],0,3),
				$a[3],$a[2],$a[1],$e[2],$e[1]);
		}

		#
		# Kennzeichnung, wenn der Kontest grad stattfindet.
		#
		if ($now>=$a && $now<=$e) {
			$dates = '*' . $dates;
		}

	}

	if ($form eq "l") {
		#
		# Langversion der Datumsausgabe
		#
		$dates = sprintf("\n    Begin: %s %02d %04d, %02d%02d UTC\n      End: %s %02d %04d, %02d%02d UTC\n",
		$lit_month[$a[4]+1],$a[3],$year,$a[2],$a[1],
		$lit_month[$e[4]+1],$e[3],$year,$e[2],$e[1]);
	}

	if ($a == -1) { $dates = ""; }
	return $dates;
}

sub weekday {

	#
	# Berechnet den Wochentag aus dem Tagesdatum
	#
	local($day,$month,$year) = @_;

	# d0 = Tage seit dem 1.1.0
	$d0 = $day + $offset[$month] + ($year)*365
	           + int(($year-1)/4)
	           - int(($year-1)/100)
	           + int(($year-1)/400);
	
	$wday = ($d0+6) % 7;		# Die Konstante ist 6 ntig, damit die
					# Wochentage wie sonst auch blich,
					# bei Sonntag anfangen sonst mte man
					# @lit_wday umstellen.
	
	if ( $debug > 1 ) {
		printf("%s, %d/%d/%d\n",$lit_wday[$wday],$day,$month,$year);

		if ( $leap_day == 0 ) { $sw='kein ' } else { $sw='ein ' }

		printf("%d. Tag des Jahres %d %sSchaltjahr, Offset=%d\n",
			$offset[$month]+$day,$year,$sw,$offset[$month]);

		printf("Tage seit dem 1. Januar des Jahres 0: %d
			\r(Zyklus=%d, Wochentag=%s)\n",
			$d0,$wday,$lit_wday[$wday]);
	}
	return $lit_wday[$wday];
}

sub calcdate {

	local($symdate,$bg_time,$duration)= @_;
	local($d,$m,$w) = (0,0,0);

	#
	# Festes Datum z.B. 2603
	#
	if ( $symdate =~ /[0-9][0-9][0-9][0-9]/ ) {

		$day = substr($symdate,0,2);
		$m = substr($symdate,2,2);

		if ( $debug > 1) {
		printf("LABEL %s, d=%s, w=%s, m=%s\n",
				$symdate,$d,$w,$m);
		}
	}

	#
	# Variables Datum, z.B. 03SUN03, LAFWX10
	#
	if ( $symdate =~ /[0-9l][0-9a][a-z][a-z][a-z][0-9][0-9]/ ) {

		$d = substr($symdate,0,2);
		$w = substr($symdate,2,3);
		$m = substr($symdate,5,2);

		$diff = $symdate;
		$diff =~ s/^.......//;
		$diff = $diff + 0;

		if ( $debug > 1) {
			printf("LABEL %s, d=%s, w=%s, m=%s\n",
				$symdate,$d,$w,$m);
		}

		if ( $d =~ /0[1234]/ ) {
                        $start_d =  1+($d-1)*7;
			$step = +1;
		}

		if ( $d eq "la" ) {
			$start_d = $days[$m];
			$step = -1;
		}
		if ( $debug > 1) {
			printf("start_d=%d, step=%d\n",$start_d,$step);
		}

		$day = $start_d;
		while ( &weekday($day,$m,$year) ne $w ) {
			if ( $debug > 1) { printf("day=%d, weekday=%s\n",
				$day,&weekday($day,$m,$year));
			}
			$day=$day+$step;
			die "ERROR: \$day > \$days[\$m]\n"
				if ($day > $days[$m]) ;
			die "ERROR: \$day < 1\n"
				if ($day < 1) ;
		}

		$day += $diff;

		if ( $debug > 1) {
			printf("day=%d, weekday=%s\n",
			$day,&weekday($day,$m,$year));
		}

	}

	#
	# Termine, die mit Ostern zu tun haben
	#
	if ( $symdate =~ /easter.*/ ) {

		$diff = $symdate;
		$diff =~ s/easter//;
		$diff = $diff + 0;

		($d,$m) = &easter($year,$diff);
		$day = $d;

		if ( $debug > 1) {
		printf("LABEL %s, diff=%s, d=%s, m=%s\n",
				$symdate,$diff,$d,$m);
		}
	}

	#
	# Startzeit berechnen
	#

	$starttime = timegm(0,$bg_time % 100,int($bg_time / 100),$day,
				$m-1,$year % 100);
	$endttime = $starttime+$duration*60;

	#
	# Ergebnis zurckgeben.
	#
	return($starttime,$endttime);
}


sub conv1 {

# Berechnen des Tagesdatums aus Tag des Jahres

	local($day_of_yr) = @_;
	local($d,$m);

	$m = 1;
	while ( $offset[$m]<$day_of_yr ) { $m++ }
	$m--;
	$d = $day_of_yr - $offset[$m];
	return($d,$m);
}

sub easter {

# /****************************************************************/
# /*                                                              */
# /*  FEasterdate - calc. easter Sunday from a year.              */
# /*                                                              */
# /*    from The Art of Computer Programming Vol 1.               */
# /*            Fundamental Algorithms                            */
# /*    by Donald Knuth.                                          */
# /*                                                              */
# /* Donated by Michael Salmon - thanks!                          */
# /*                                                              */
# /* I haven't examined this in detail, but I *think* int         */
# /* arithmetic is fine, even on 16-bit machines.                 */
# /*                                                              */
# /****************************************************************/

	local($y) = @_;
	local($m, $d, $g, $c, $x, $z, $e, $n);

	$g = int($y % 19) + 1;			# golden number
	$c = int($y / 100) + 1; 		# century
	$x = int((3 * $c)/4) - 12;        	# correction for
						# non-leap year centuries
	$z = int((8 * $c + 5)/25) - 5;   	# special constant for moon sync
	$d = int(5 * $y)/4 - $x - 10;   	# find sunday
	$e = (11 * $g + 20 + $z - $x) % 30;	# calc epact
	if ( $e < 0 ) { $e = $e + 30; }
	if ( $e == 24 || ($e == 25 && $g > 11)) {
		$e++;
	}

	$n = 44 - $e;				# find full moon
	if ( $n < 21 ) { $n = $n + 30; }	# after 21st
	$d = $n + 7 - ($d + $n)%7;		# calc sunday after

	if ($d <= 31) { $m = 3; }
	else {
		$d = $d - 31;
		$m = 4;
	}

	$day_of_yr = $offset[$m]+$d+$diff;	# Tag des Jahres mu
						# benutzt werden, damit
						# Differenz gebildet
						# werden kann. Danach wird
						# wieder in Tag und Monat
						# zurckkonvertiert
	($d,$m) = conv1($day_of_yr);

	return($d,$m)
}

sub chk_index {

	# prfe, ob ein Indexfile vorhanden ist und ob es neueren Datums
	# ist, als die neueste Datei im Datenverzeichnis

	$index_filedate = (stat("$dir/$index"))[9];
	$c2 = 0;

	$newest_file = `/bin/ls -1rt $dir/*.txt | tail -1`;
	chop($newest_file);
	$newest_filedate = (stat($newest_file))[9];

	if ($index_filedate < $newest_filedate) {

		print "A new index file is being generated, QRX.\n";

		chomp($cwd = `pwd`);
		chdir($dir);
		open(INDEX,"> $index");

		for $i (`ls *.txt`) {
			if ( $debug > 1) {
				print "$i\n";
			}
			open(IN,"< $i");
			$name = <IN>; # erste Zeile enthlt vollen Namen
			$name =~ tr /\012\015//d;
			$c1++;
			while (<IN>) {
				tr /\012\015//d;
				if ( /^\{.*\}/ ) {
					printf INDEX ("%s\t%s\t%s\n",
						$_,$name,$i);
					$c2++;
				}
			}
			close(IN);
		}
		close(INDEX);
		chdir($cwd);

		print "$c1 contests, $c2 time segments.\n";
	}
}
