summaryrefslogtreecommitdiff
path: root/Master/tlpkg/TeXLive/TLUtils.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/TeXLive/TLUtils.pm')
-rw-r--r--Master/tlpkg/TeXLive/TLUtils.pm399
1 files changed, 347 insertions, 52 deletions
diff --git a/Master/tlpkg/TeXLive/TLUtils.pm b/Master/tlpkg/TeXLive/TLUtils.pm
index 4b7dafbc3f3..cd5fc335235 100644
--- a/Master/tlpkg/TeXLive/TLUtils.pm
+++ b/Master/tlpkg/TeXLive/TLUtils.pm
@@ -32,6 +32,7 @@ C<TeXLive::TLUtils> -- utilities used in the TeX Live infrastructure
TeXLive::TLUtils::tl_tmpdir();
TeXLive::TLUtils::xchdir($dir);
TeXLive::TLUtils::xsystem(@args);
+ TeXLive::TLUtils::run_cmd($cmd);
=head2 File Utilities
@@ -56,6 +57,7 @@ C<TeXLive::TLUtils> -- utilities used in the TeX Live infrastructure
TeXLive::TLUtils::create_language_def($tlpdb,$dest,$localconf);
TeXLive::TLUtils::install_packages($from_tlpdb,$media,$to_tlpdb,$what,$opt_src, $opt_doc)>);
TeXLive::TLUtils::install_package($what, $filelistref, $target, $platform);
+ TeXLive::TLUtils::do_postaction($how, $tlpobj);
=head2 Miscellaneous
@@ -113,10 +115,11 @@ BEGIN {
&give_ctan_mirror
&tlmd5
&xsystem
+ &run_cmd
);
@EXPORT = qw(setup_programs download_file process_logging_options
tlwarn info log debug ddebug dddebug debug_hash
- win32 xchdir xsystem);
+ win32 xchdir xsystem run_cmd);
}
use Cwd;
@@ -398,6 +401,25 @@ sub xsystem
}
}
+=item C<run_cmd($cmd)>
+
+runs a command and captures its output. Then returns a list with the
+output as first element and the return value (exit code) as second.
+
+=cut
+
+sub run_cmd {
+ my $cmd = shift;
+ my $output = `$cmd`;
+ $retval = $?
+ if ($retval != 0) {
+ $retval /= 256 if $retval > 0;
+ }
+ return ($output, $retval);
+}
+
+
+
=back
@@ -949,6 +971,7 @@ sub install_packages {
my $starttime = time();
foreach my $package (@packs) {
my $tlpobj = $tlpobjs{$package};
+ my $reloc = $tlpobj->relocated;
$n++;
my $remtime = "??:??";
my $tottime = "??:??";
@@ -1006,16 +1029,16 @@ sub install_packages {
} elsif ($media eq 'CD') {
if (-r "$root/$Archive/$package.zip") {
$container = "$root/$Archive/$package.zip";
- } elsif (-r "$root/$Archive/$package.tar.lzma") {
- $container = "$root/$Archive/$package.tar.lzma";
+ } elsif (-r "$root/$Archive/$package.tar.xz") {
+ $container = "$root/$Archive/$package.tar.xz";
} else {
- tlwarn("No package $package (.zip or .lzma) in $root/$Archive\n");
+ tlwarn("No package $package (.zip or .xz) in $root/$Archive\n");
next;
}
} elsif ($media eq 'NET') {
$container = "$root/$Archive/$package.$DefaultContainerExtension";
}
- if (!install_package($container, $tlpobj->containersize,
+ if (!install_package($container, $reloc, $tlpobj->containersize,
$tlpobj->containermd5, \@installfiles,
$totlpdb->root, $vars{'this_platform'})) {
# we already warn in install_package that something bad happened,
@@ -1036,8 +1059,8 @@ sub install_packages {
# - there are actually src/doc files present
if ($container_src_split && $opt_src && $tlpobj->srcfiles) {
my $srccontainer = $container;
- $srccontainer =~ s/(\.tar\.lzma|\.zip)$/.source$1/;
- if (!install_package($srccontainer, $tlpobj->srccontainersize,
+ $srccontainer =~ s/(\.tar\.xz|\.zip)$/.source$1/;
+ if (!install_package($srccontainer, $reloc, $tlpobj->srccontainersize,
$tlpobj->srccontainermd5, \@installfiles,
$totlpdb->root, $vars{'this_platform'})) {
return 0;
@@ -1045,8 +1068,8 @@ sub install_packages {
}
if ($container_doc_split && $real_opt_doc && $tlpobj->docfiles) {
my $doccontainer = $container;
- $doccontainer =~ s/(\.tar\.lzma|\.zip)$/.doc$1/;
- if (!install_package($doccontainer,
+ $doccontainer =~ s/(\.tar\.xz|\.zip)$/.doc$1/;
+ if (!install_package($doccontainer, $reloc,
$tlpobj->doccontainersize,
$tlpobj->doccontainermd5, \@installfiles,
$totlpdb->root, $vars{'this_platform'})) {
@@ -1064,7 +1087,7 @@ sub install_packages {
}
$totlpdb->add_tlpobj($tlpobj);
# we have to write out the tlpobj file since it is contained in the
- # archives (.tar.lzma) but at DVD install time we don't have them
+ # archives (.tar.xz) but at DVD install time we don't have them
my $tlpod = $totlpdb->root . "/tlpkg/tlpobj";
mkdirhier( $tlpod );
open(TMP,">$tlpod/".$tlpobj->name.".tlpobj") ||
@@ -1083,7 +1106,7 @@ sub install_packages {
}
-=item C<install_package($what, $size, $md5, $filelistref, $target, $platform)>
+=item C<install_package($what, $reloc, $size, $md5, $filelistref, $target, $platform)>
This function installs the files given in @$filelistref from C<$what>
into C<$target>.
@@ -1097,29 +1120,34 @@ the way. In this case the list C<@$filelistref> is not taken into
account.
If C<$what> starts with C<http://> or C<ftp://> then C<$what> is
-downloaded from the net and piped through C<lzmadec> and C<tar>.
+downloaded from the net and piped through C<xzdec> and C<tar>.
-If $what ends with C<.tar.lzma> (but does not start with C<http://> or
+If $what ends with C<.tar.xz> (but does not start with C<http://> or
C<ftp://>, but possibly with C<file:/>) it is assumed to be a readable
-file on the system and is likewise piped through C<lzmadec> and C<tar>.
+file on the system and is likewise piped through C<xzdec> and C<tar>.
In both of these cases currently the list C<$@filelistref> currently
is not taken into account (should be fixed!).
+if C<$reloc> is true the container (NET or CD mode) is packaged in a way
+that the initial texmf-dist is missing.
+
Returns 1 on success and 0 on error.
=cut
sub install_package {
- my ($what, $whatsize, $whatmd5, $filelistref, $target, $platform) = @_;
+ my ($what, $reloc, $whatsize, $whatmd5, $filelistref, $target, $platform) = @_;
my @filelist = @$filelistref;
+ my $tempdir = "$target/temp";
+
# we assume that $::progs has been set up!
my $wget = $::progs{'wget'};
- my $lzmadec = $::progs{'lzmadec'};
- if (!defined($wget) || !defined($lzmadec)) {
- tlwarn("install_package: wget/lzmadec programs not set up properly.\n");
+ my $xzdec = $::progs{'xzdec'};
+ if (!defined($wget) || !defined($xzdec)) {
+ tlwarn("install_package: wget/xzdec programs not set up properly.\n");
return 0;
}
if (ref $what) {
@@ -1132,35 +1160,43 @@ sub install_package {
mkdirhier("$target/$dn");
copy "$root/$file", "$target/$dn";
}
- } elsif ($what =~ m,\.tar.lzma$,) {
+ } elsif ($what =~ m,\.tar.xz$,) {
# this is the case when we install from CD or the NET
#
- # in all other cases we create temp files .tar.lzma (or use the present
- # one), lzmadec them, and then call tar
+ # in all other cases we create temp files .tar.xz (or use the present
+ # one), xzdec them, and then call tar
+
+ # if we are unpacking a relocated container we adjust the target
+ if ($reloc) {
+ $target .= "/$TeXLive::TLConfig::RelocTree" if $reloc;
+ mkdir($target) if (! -d $target);
+ }
my $fn = basename($what);
- mkdirhier("$target/temp");
- my $lzmafile = "$target/temp/$fn";
- my $tarfile = "$target/temp/$fn"; $tarfile =~ s/\.lzma$//;
- my $lzmafile_quote = $lzmafile;
+ my $pkg = $fn;
+ $pkg =~ s/\.tar\.xz$//;
+ mkdirhier("$tempdir");
+ my $xzfile = "$tempdir/$fn";
+ my $tarfile = "$tempdir/$fn"; $tarfile =~ s/\.xz$//;
+ my $xzfile_quote = $xzfile;
my $tarfile_quote = $tarfile;
if (win32()) {
- $lzmafile =~ s!/!\\!g;
+ $xzfile =~ s!/!\\!g;
$tarfile =~ s!/!\\!g;
$target =~ s!/!\\!g;
}
- $lzmafile_quote = "\"$lzmafile\"";
+ $xzfile_quote = "\"$xzfile\"";
$tarfile_quote = "\"$tarfile\"";
my $gotfiledone = 0;
- if (-r $lzmafile) {
+ if (-r $xzfile) {
# check that the downloaded file is not partial
if ($whatsize >= 0) {
# we have the size given, so check that first
- my $size = (stat $lzmafile)[7];
+ my $size = (stat $xzfile)[7];
if ($size == $whatsize) {
# we want to check also the md5sum if we have it present
if ($whatmd5) {
- if (tlmd5($lzmafile) eq $whatmd5) {
+ if (tlmd5($xzfile) eq $whatmd5) {
$gotfiledone = 1;
} else {
tlwarn("Downloaded $what, size equal, but md5sum differs;\n",
@@ -1174,12 +1210,12 @@ sub install_package {
}
} else {
tlwarn("Partial download of $what found, removing it.\n");
- unlink($tarfile, $lzmafile);
+ unlink($tarfile, $xzfile);
}
} else {
# ok no size information, hopefully we have md5 sums
if ($whatmd5) {
- if (tlmd5($lzmafile) eq $whatmd5) {
+ if (tlmd5($xzfile) eq $whatmd5) {
$gotfiledone = 1;
} else {
tlwarn("Downloaded file, but md5sum differs, removing it.\n");
@@ -1190,39 +1226,44 @@ sub install_package {
$gotfiledone = 1;
}
}
- debug("Reusing already downloaded container $lzmafile\n")
+ debug("Reusing already downloaded container $xzfile\n")
if ($gotfiledone);
}
if (!$gotfiledone) {
if ($what =~ m,http://|ftp://,) {
# we are installing from the NET
# download the file and put it into temp
- if (!download_file($what, $lzmafile) || (! -r $lzmafile)) {
+ if (!download_file($what, $xzfile) || (! -r $xzfile)) {
tlwarn("Downloading $what did not succeed.\n");
return 0;
}
} else {
# we are installing from CD
# copy it to temp
- copy($what, "$target/temp");
+ copy($what, $tempdir);
}
}
- debug("un-lzmaing $lzmafile to $tarfile\n");
- system("$lzmadec < $lzmafile_quote > $tarfile_quote");
+ debug("un-xzing $xzfile to $tarfile\n");
+ system("$xzdec < $xzfile_quote > $tarfile_quote");
if (! -f $tarfile) {
- tlwarn("Unpacking $lzmafile did not succeed.\n");
+ tlwarn("Unpacking $xzfile did not succeed.\n");
return 0;
}
if (!TeXLive::TLUtils::untar($tarfile, $target, 1)) {
tlwarn("Un-tarring $tarfile did not succeed.\n");
return 0;
}
+ # we remove the created .tlpobj it is recreated anyway in
+ # install_packages above in the right place. This way we also
+ # get rid of the $pkg.source.tlpobj which are useless
+ unlink ("$target/tlpkg/tlpobj/$pkg.tlpobj")
+ if (-r "$target/tlpkg/tlpobj/$pkg.tlpobj");
if ($what =~ m,http://|ftp://,) {
# we downloaded the original .tar.lzma from the net, so we keep it
} else {
- # we are downloading it from CD, so we can unlink it to save
+ # we are downloading it from CD, so we can unlink it to save
# disk space
- unlink($lzmafile);
+ unlink($xzfile);
}
} else {
tlwarn("Sorry, no idea how to install $what\n");
@@ -1231,6 +1272,261 @@ sub install_package {
return 1;
}
+=item C<do_postaction($how, $tlpobj, $do_fileassocs, $do_shortcuts, $do_script)>
+
+Evaluates the C<postaction> fields in the C<$tlpobj>. The first parameter
+can be either C<install> or C<remove>. The second gives the TLPOBJ whos
+postactions should be evaluated, and the last three arguments specify
+what type of postactions should (or shouldn't) be evaluated.
+
+Returns 1 on success, and 0 on failure.
+
+=cut
+
+sub do_postaction {
+ my ($how, $tlpobj, $do_fileassocs, $do_shortcuts, $do_script) = @_;
+ my $ret = 1;
+ if (!defined($tlpobj)) {
+ tlwarn("do_postaction: didn't get a tlpobj\n");
+ return 0;
+ }
+ debug("running postaction=$how for " . $tlpobj->name . "\n")
+ if $tlpobj->postactions;
+ for my $pa ($tlpobj->postactions) {
+ if ($pa =~ m/^\s*shortcut\s+(.*)\s*$/) {
+ next unless $do_shortcuts;
+ $ret &&= _do_postaction_shortcut($how, $tlpobj, $1);
+ } elsif ($pa =~ m/\s*filetype\s+(.*)\s*$/) {
+ next unless $do_fileassocs;
+ $ret &&= _do_postaction_filetype($how, $tlpobj, $1);
+ } elsif ($pa =~ m/\s*fileassoc\s+(.*)\s*$/) {
+ next unless $do_fileassocs;
+ $ret &&= _do_postaction_fileassoc($how, $tlpobj, $1);
+ } elsif ($pa =~ m/\s*script\s+(.*)\s*$/) {
+ next unless $do_script;
+ $ret &&= _do_postaction_script($how, $tlpobj, $1);
+ } else {
+ tlwarn("do_postaction: don't know how to do $pa\n");
+ $ret = 0;
+ }
+ }
+ # nothing to do
+ return $ret;
+}
+
+sub _do_postaction_fileassoc {
+ my ($how, $tlpobj, $pa) = @_;
+ return 1 unless win32();
+ my ($errors, %keyval) =
+ parse_into_keywords($pa, qw/extension filetype/);
+
+ if ($errors) {
+ tlwarn("parsing the postaction line >>$pa<< did not succeed!\n");
+ return 0;
+ }
+
+ # name can be an arbitrary string
+ if (!defined($keyval{'extension'})) {
+ tlwarn("extension of fileassoc postaction not given\n");
+ return 0;
+ }
+ my $extension = $keyval{'extension'};
+
+ # cmd can be an arbitrary string
+ if (!defined($keyval{'filetype'})) {
+ tlwarn("filetype of fileassoc postaction not given\n");
+ return 0;
+ }
+ my $filetype = $keyval{'filetype'};
+
+ if ($how eq "install") {
+ TeXLive::TLWinGoo::register_extension($extension, $filetype);
+ } elsif ($how eq "remove") {
+ TeXLive::TLWinGoo::unregister_extension($extension);
+ } else {
+ tlwarn("Unknown mode $how\n");
+ return 0;
+ }
+ return 1;
+}
+sub _do_postaction_filetype {
+ my ($how, $tlpobj, $pa) = @_;
+ return 1 unless win32();
+ my ($errors, %keyval) =
+ parse_into_keywords($pa, qw/name cmd/);
+
+ if ($errors) {
+ tlwarn("parsing the postaction line >>$pa<< did not succeed!\n");
+ return 0;
+ }
+
+ # name can be an arbitrary string
+ if (!defined($keyval{'name'})) {
+ tlwarn("name of filetype postaction not given\n");
+ return 0;
+ }
+ my $name = $keyval{'name'};
+
+ # cmd can be an arbitrary string
+ if (!defined($keyval{'cmd'})) {
+ tlwarn("cmd of filetype postaction not given\n");
+ return 0;
+ }
+ my $cmd = $keyval{'cmd'};
+
+ if ($how eq "install") {
+ TeXLive::TLWinGoo::register_file_type($name, $cmd);
+ } elsif ($how eq "remove") {
+ TeXLive::TLWinGoo::unregister_file_type($name);
+ } else {
+ tlwarn("Unknown mode $how\n");
+ return 0;
+ }
+ return 1;
+}
+
+sub _do_postaction_script {
+ my ($how, $tlpobj, $pa) = @_;
+ my ($errors, %keyval) =
+ parse_into_keywords($pa, qw/file filew32/);
+
+ if ($errors) {
+ tlwarn("parsing the postaction line >>$pa<< did not succeed!\n");
+ return 0;
+ }
+
+ # file can be an arbitrary string
+ if (!defined($keyval{'file'})) {
+ tlwarn("filename of script not given\n");
+ return 0;
+ }
+ my $file = $keyval{'file'};
+ if (win32() && defined($keyval{'filew32'})) {
+ $file = $keyval{'filew32'};
+ }
+ my $texdir = `kpsewhich -var-value=SELFAUTOPARENT`;
+ chomp($texdir);
+ my @syscmd;
+ if ($file =~ m/\.pl$/i) {
+ # we got a perl script, call it via perl
+ push @syscmd, "perl", "$texdir/$file";
+ } elsif ($file =~ m/\.texlua$/i) {
+ # we got a texlua script, call it via texlua
+ push @syscmd, "texlua", "$texdir/$file";
+ } else {
+ # we got anything else, call it directly and hope it is excutable
+ push @syscmd, "$texdir/$file";
+ }
+ push @syscmd, $how, $texdir;
+ my $ret = system (@syscmd);
+ if ($ret != 0) {
+ $ret /= 256 if $ret > 0;
+ my $pwd = cwd ();
+ warn "$0: calling post action script $file did not succeed in $pwd, status $ret";
+ return 0;
+ }
+ return 1;
+}
+
+sub _do_postaction_shortcut {
+ my ($how, $tlpobj, $pa) = @_;
+ return 1 unless win32();
+ my ($errors, %keyval) =
+ parse_into_keywords($pa, qw/type name icon cmd args hide/);
+
+ if ($errors) {
+ tlwarn("parsing the postaction line >>$pa<< did not succeed!\n");
+ return 0;
+ }
+
+ # type can be either menu or desktop
+ if (!defined($keyval{'type'})) {
+ tlwarn("type of shortcut postaction not given\n");
+ return 0;
+ }
+ my $type = $keyval{'type'};
+ if (($type ne "menu") && ($type ne "desktop")) {
+ tlwarn("type of shortcut postaction $type is unknown (menu, desktop)\n");
+ return 0;
+ }
+
+ # name can be an arbitrary string
+ if (!defined($keyval{'name'})) {
+ tlwarn("name of shortcut postaction not given\n");
+ return 0;
+ }
+ my $name = $keyval{'name'};
+
+ # icon, cmd, args is optional
+ my $icon = (defined($keyval{'icon'}) ? $keyval{'icon'} : '');
+ my $cmd = (defined($keyval{'cmd'}) ? $keyval{'cmd'} : '');
+ my $args = (defined($keyval{'args'}) ? $keyval{'args'} : '');
+
+ # hide can be only 0 or 1, and defaults to 0
+ my $hide = (defined($keyval{'hide'}) ? $keyval{'hide'} : 0);
+ if (($hide ne "0") && ($hide ne "1")) {
+ tlwarn("hide of shortcut postaction $hide is unknown (0, 1)\n");
+ return 0;
+ }
+
+ if ($how eq "install") {
+ my $texdir = `kpsewhich -var-value=SELFAUTOPARENT`;
+ chomp($texdir);
+ my $texdir_bsl = conv_to_w32_path($texdir);
+ $icon =~ s!^TEXDIR/!$texdir/!;
+ $args =~ s!^TEXDIR/!$texdir/!;
+ $args = conv_to_w32_path($args);
+ if ($type eq "menu") {
+ TeXLive::TLWinGoo::add_menu_shortcut(
+ $TeXLive::TLConfig::WindowsMainMenuName,
+ $name, $icon, $cmd, $args, $hide);
+ } elsif ($type eq "desktop") {
+ TeXLive::TLWinGoo::add_desktop_shortcut(
+ $name, $icon, $cmd, $args, $hide);
+ } else {
+ tlwarn("Unknown type of shortcut: $type\n");
+ return 0;
+ }
+ } elsif ($how eq "remove") {
+ if ($type eq "menu") {
+ TeXLive::TLWinGoo::remove_menu_shortcut(
+ $TeXLive::TLConfig::WindowsMainMenuName, $name);
+ } elsif ($type eq "desktop") {
+ TeXLive::TLWinGoo::remove_desktop_shortcut($name);
+ } else {
+ tlwarn("Unknown type of shortcut: $type\n");
+ return 0;
+ }
+ } else {
+ tlwarn("Unknown mode $how\n");
+ return 0;
+ }
+ return 1;
+}
+
+sub parse_into_keywords {
+ my ($str, @keys) = @_;
+ my @words = quotewords('\s+', 0, $str);
+ my %ret;
+ my $error = 0;
+ while (@words) {
+ $_ = shift @words;
+ if (/^([^=]+)=(.*)$/) {
+ $ret{$1} = $2;
+ } else {
+ tlwarn("parser found a invalid word in parsing keys: $_\n");
+ $error++;
+ $ret{$_} = "";
+ }
+ }
+ for my $k (keys %ret) {
+ if (!member($k, @keys)) {
+ $error++;
+ tlwarn("parser found invalid keyword: $k\n");
+ }
+ }
+ return($error, %ret);
+}
=item C<untar($tarfile,$targetdir, $remove_tarfile)>
@@ -1270,13 +1566,12 @@ sub untar {
return $ret;
}
-
=item C<setup_programs($bindir, $platform)>
Populate the global C<$::progs> hash containing the paths to the
-programs C<wget>, C<tar>, C<lzmadec>. The C<$bindir> argument specifies
-the path to the location of the C<lzmadec> binaries, the C<$platform>
+programs C<wget>, C<tar>, C<xzdec>. The C<$bindir> argument specifies
+the path to the location of the C<xzdec> binaries, the C<$platform>
gives the TeX Live platform name, used as the extension on our
executables. If a program is not present in the TeX Live tree, we also
check along PATH (without the platform extension.)
@@ -1290,17 +1585,17 @@ sub setup_programs {
my $ok = 1;
$::progs{'wget'} = "wget";
- $::progs{'lzmadec'} = "lzmadec";
- $::progs{'lzma'} = "lzma";
+ $::progs{'xzdec'} = "xzdec";
+ $::progs{'xz'} = "xz";
$::progs{'tar'} = "tar";
if ($^O =~ /^MSWin(32|64)$/i) {
$::progs{'wget'} = conv_to_w32_path("$bindir/wget/wget.exe");
$::progs{'tar'} = conv_to_w32_path("$bindir/tar.exe");
- $::progs{'lzmadec'} = conv_to_w32_path("$bindir/lzma/lzmadec.win32.exe");
- $::progs{'lzma'} = conv_to_w32_path("$bindir/lzma/lzma.exe");
- for my $prog ("lzmadec", "wget") {
- my $opt = $prog eq "lzmadec" ? "--help" : "--version";
+ $::progs{'xzdec'} = conv_to_w32_path("$bindir/xz/xzdec.exe");
+ $::progs{'xz'} = conv_to_w32_path("$bindir/xz/xz.exe");
+ for my $prog ("xzdec", "wget") {
+ my $opt = $prog eq "xzdec" ? "--help" : "--version";
my $ret = system("$::progs{$prog} $opt >nul 2>&1"); # on windows
if ($ret != 0) {
warn "TeXLive::TLUtils::setup_programs (w32) failed"; # no nl for perl
@@ -1322,8 +1617,8 @@ sub setup_programs {
}
my $s = 0;
$s += setup_unix_one('wget', "$bindir/wget/wget.$platform", "--version");
- $s += setup_unix_one('lzmadec',"$bindir/lzma/lzmadec.$platform","--help");
- $s += setup_unix_one('lzma', "$bindir/lzma/lzma.$platform", "notest");
+ $s += setup_unix_one('xzdec',"$bindir/xz/xzdec.$platform","--help");
+ $s += setup_unix_one('xz', "$bindir/xz/xz.$platform", "notest");
$ok = ($s == 3); # failure return unless all are present.
}
@@ -1600,7 +1895,7 @@ improved (checking for duplicates).
sub create_fmtutil {
my ($tlpdb,$dest,$localconf) = @_;
my @lines = $tlpdb->fmtutil_cnf_lines;
- _create_config_files($tlpdb, "texmf/fmtutil/fmtutil-hdr.cnf", $dest,
+ _create_config_files($tlpdb, "texmf/web2c/fmtutil-hdr.cnf", $dest,
$localconf, 0, '#', \@lines);
}