3
BEGIN { # Work-around for bug #479711 in perl
4
$ENV{PERL_DL_NONLAZY} = 1;
14
# FIXME: send to FSF ?
17
printf _g("Debian %s version %s.\n"), $progname, $version;
20
Copyright (C) 1994,1995 Ian Jackson.");
23
This is free software; see the GNU General Public Licence version 2 or
24
later for copying conditions. There is NO warranty.
31
"Usage: %s [<options> ...] [--] <filename>
34
--section <regexp> <title>
35
put the new entry in the <regex> matched section
36
or create a new one with <title> if non-existent.
37
--menuentry=<text> set the menu entry.
38
--description=<text> set the description to be used in the menu entry.
39
--info-file=<path> specify info file to install in the directory.
40
--dir-file=<path> specify file name of info directory file.
41
--infodir=<directory> same as '--dir-file=<directory>/dir'.
42
--info-dir=<directory> likewise.
43
--keep-old do not replace entries nor remove empty ones.
44
--remove remove the entry specified by <filename> basename.
45
--remove-exactly remove the exact <filename> entry.
46
--test enables test mode (no actions taken).
47
--debug enables debug mode (show more information).
48
--quiet do not show output messages.
49
--help show this help message.
50
--version show the version.
54
$dirfile = '/usr/share/info/dir';
56
$Text::Wrap::columns=$maxwidth;
57
$backup='/var/backups/infodir.bak';
58
$default='/usr/share/base-files/info.dir';
73
$0 =~ m|[^/]+$|; $name= $&;
75
while ($ARGV[0] =~ m/^--/) {
78
if ($_ eq '--version') {
79
&version(STDOUT); exit 0;
80
} elsif ($_ eq '--quiet') {
82
} elsif ($_ eq '--test') {
84
} elsif ($_ eq '--keep-old') {
86
} elsif ($_ eq '--remove') {
88
} elsif ($_ eq '--remove-exactly') {
91
} elsif ($_ eq '--help') {
92
&usage(STDOUT); exit 0;
93
} elsif ($_ eq '--version') {
95
} elsif ($_ eq '--debug') {
96
open(DEBUG,">&STDERR")
97
|| &quit(sprintf(_g("could not open stderr for output! %s"), $!));
99
} elsif ($_ eq '--section') {
101
printf STDERR _g("%s: --section needs two more args")."\n", $name;
102
&usage(STDERR); exit 1;
104
$sectionre= shift(@ARGV);
105
$sectiontitle= shift(@ARGV);
106
} elsif (m/^--(c?align|maxwidth)=([0-9]+)$/) {
107
warn(sprintf(_g("%s: option --%s is deprecated (ignored)"), $name, $1)."\n");
108
} elsif (m/^--info-?dir=/) {
109
$dirfile = $' . '/dir';
110
} elsif (m/^--info-file=/) {
112
} elsif (m/^--menuentry=/) {
114
} elsif (m/^--description=/) {
116
} elsif (m/^--dir-file=/) { # for compatibility with GNU install-info
119
printf STDERR _g("%s: unknown option \`%s'")."\n", $name, $_;
120
&usage(STDERR); exit 1;
124
if (!@ARGV) { &usage(STDERR); exit 1; }
127
$filename= shift(@ARGV);
128
$name = "$name($filename)";
130
if (@ARGV) { printf STDERR _g("%s: too many arguments")."\n", $name; &usage(STDERR); exit 1; }
133
printf(STDERR _g("%s: --section ignored with --remove")."\n", $name) if length($sectiontitle);
134
printf(STDERR _g("%s: --description ignored with --remove")."\n", $name) if length($description);
137
printf(STDERR _g("%s: test mode - dir file will not be updated")."\n", $name)
138
if $nowrite && !$quiet;
140
umask(umask(0777) & ~0444);
142
if($remove_exactly) {
143
$remove_exactly = $filename;
146
$filename =~ m|[^/]+$|; $basename= $&; $basename =~ s/(\.info)?(\.gz)?$//;
148
# The location of the info files from the dir entry, i.e. (emacs-20/emacs).
151
&dprint("dirfile='$dirfile' filename='$filename' maxwidth='$maxwidth'");
152
&dprint("menuentry='$menuentry' basename='$basename'");
153
&dprint("description='$description' remove=$remove");
157
if (!-f $filename && -f "$filename.gz" || $filename =~ s/\.gz$//) {
158
$filename= "gzip -cd <$filename.gz |"; $pipeit= 1;
159
} elsif (-f $filename) {
160
$filename= "< $filename";
162
die "$progname: File $filename not found\n";
165
if (!length($description)) {
167
open(IF,"$filename") || &quit(sprintf(_g("unable to read %s: %s"), $filename, $!));
170
m/^START-INFO-DIR-ENTRY$/ && last;
171
m/^INFO-DIR-SECTION (.+)$/ && do {
172
$sectiontitle = $1 unless ($sectiontitle);
173
$sectionre = '^'.quotemeta($1) unless ($sectionre);
176
while(<IF>) { last if m/^END-INFO-DIR-ENTRY$/; $asread.= $_; }
181
close(IF); &checkpipe;
182
if ($asread =~ m/(\*\s*[^:]+:\s*\(([^\)]+)\).*\. *.*\n){2}/) {
186
&dprint("multiline '$asread'");
187
} elsif ($asread =~ m/^\*\s*([^:]+):(\s*\(([^\)]+)\)\.|:)\s*/) {
191
&dprint("infile menuentry '$menuentry' description '$description'");
192
} elsif (length($asread)) {
193
printf STDERR _g("%s: warning, ignoring confusing INFO-DIR-ENTRY in file.")."\n", $name;
197
if (length($infoentry)) {
200
print "$`\n" unless $quiet;
201
$infoentry =~ m/^\*\s*([^:]+):\s*\(([^\)]+)\)/ ||
202
&quit(_g("invalid info entry")); # internal error
208
if (!length($description)) {
209
open(IF,"$filename") || &quit(_g("unable to read %s: %s"), $filename, $!);
212
if (m/^\s*[Tt]his file documents/) {
217
if (length($asread)) {
218
while(<IF>) { last if m/^\s*$/; $asread.= $_; }
219
$description= $asread;
224
close(IF); &checkpipe;
227
if (!length($description)) {
229
No \`START-INFO-DIR-ENTRY' and no \`This file documents'.
230
%s: unable to determine description for \`dir' entry - giving up
235
$description =~ s/^\s*(.)//; $_=$1; y/a-z/A-Z/;
236
$description= $_ . $description;
238
if (!length($menuentry)) {
239
$menuentry= $basename; $menuentry =~ s/\Winfo$//;
240
$menuentry =~ s/^.//; $_=$&; y/a-z/A-Z/;
241
$menuentry= $_ . $menuentry;
244
&dprint("menuentry='$menuentry' description='$description'");
247
$cprefix= sprintf("* %s: (%s).", $menuentry, $fileinentry);
249
$cprefix= sprintf("* %s: (%s).", $menuentry, $basename);
253
$lprefix= length($cprefix);
254
if ($lprefix < $align) {
255
$cprefix .= ' ' x ($align - $lprefix);
258
$prefix= "\n". (' 'x $calign);
259
$cwidth= $maxwidth+1;
261
for $_ (split(/\s+/,$description)) {
263
$cwidth++; $cwidth += $l;
264
if ($cwidth > $maxwidth) {
265
$infoentry .= $cprefix;
266
$cwidth= $lprefix+1+$l;
267
$cprefix= $prefix; $lprefix= $calign;
269
$infoentry.= ' '; $infoentry .= $_;
273
print $infoentry unless $quiet;
274
$sortby= $menuentry; $sortby =~ y/A-Z/a-z/;
279
if (!$nowrite && ( ! -e $dirfile || ! -s _ )) {
281
printf( STDERR _g("%s: no file %s, retrieving backup file %s.")."\n",
282
$name, $dirfile, "$backup" );
283
if (system ('cp', $backup, $dirfile)) {
284
printf( STDERR _g("%s: copying %s to %s failed, giving up: %s")."\n",
285
$name, $backup, $dirfile, $! );
290
printf( STDERR _g("%s: no backup file %s available, retrieving default file.")."\n",
293
if (system('cp', $default, $dirfile)) {
294
printf( STDERR _g("%s: copying %s to %s failed, giving up: %s")."\n",
295
$name, $default, $dirfile, $! );
299
printf STDERR _g("%s: no backup file %s available.")."\n", $name, $backup;
300
printf STDERR _g("%s: no default file %s available, giving up.")."\n", $name, $default;
306
if (!$nowrite && !link($dirfile, "$dirfile.lock")) {
307
printf( STDERR _g("%s: failed to lock dir for editing! %s")."\n",
309
printf( STDERR _g("try deleting %s?")."\n", "$dirfile.lock")
314
open(OLD, $dirfile) || &ulquit(sprintf(_g("unable to open %s: %s"), $dirfile, $!));
316
eof(OLD) || &ulquit(sprintf(_g("unable to read %s: %s"), $dirfile, $!));
317
close(OLD) || &ulquit(sprintf(_g("unable to close %s after read: %s"),
320
while (($#work >= 0) && ($work[$#work] !~ m/\S/)) { $#work--; }
325
last if (m/^\*\s*Menu:/i);
333
$target_entry = $fileinentry;
335
$target_entry = $basename;
338
for ($i=0; $i<=$#work; $i++) {
339
next unless $work[$i] =~ m/^\*\s*[^:]+:\s*\(([^\)]+)\).*\.\s/;
340
last if $1 eq $target_entry || $1 eq "$target_entry.info";
342
for ($j=$i; $j<=$#work+1; $j++) {
343
next if $work[$j] =~ m/^\s+\S/;
344
last unless $work[$j] =~ m/^\* *[^:]+: *\(([^\)]+)\).*\.\s/;
345
last unless $1 eq $target_entry || $1 eq "$target_entry.info";
350
printf(_g("%s: existing entry for \`%s' not replaced")."\n", $name, $target_entry) unless $quiet;
353
printf(_g("%s: replacing existing dir entry for \`%s'")."\n", $name, $target_entry) unless $quiet;
356
@work= (@work[0..$i-1], @work[$j..$#work]);
357
} elsif (length($sectionre)) {
359
for ($i=0; $i<=$#work; $i++) {
362
next unless m/$sectionre/io;
366
printf(_g("%s: creating new section \`%s'")."\n", $name, $sectiontitle) unless $quiet;
367
for ($i= $#work; $i>=0 && $work[$i] =~ m/\S/; $i--) { }
368
if ($i <= 0) { # We ran off the top, make this section and Misc.
369
printf(_g("%s: no sections yet, creating Miscellaneous section too.")."\n", $name)
371
@work= ("\n", "$sectiontitle\n", "\n", "Miscellaneous:\n", @work);
374
@work= (@work[0..$i], "$sectiontitle\n", "\n", @work[$i+1..$#work]);
378
while ($mss <= $#work) {
379
$work[$mss] =~ m/\S/ || last;
380
$work[$mss] =~ m/^\* *([^:]+):/ || ($mss++, next);
383
last if $_ gt $sortby;
387
printf(_g("%s: no section specified for new entry, placing at end")."\n", $name)
392
@work= (@work[0..$mss-1], map("$_\n",split(/\n/,$infoentry)), @work[$mss..$#work]);
398
if($remove_exactly) {
399
$target_entry = $remove_exactly;
401
$target_entry = $basename;
404
for ($i=0; $i<=$#work; $i++) {
405
next unless $work[$i] =~ m/^\* *([^:]+): *\((\w[^\)]*)\)/;
406
$tme= $1; $tfile= $2; $match= $&;
407
next unless $tfile eq $target_entry;
408
last if !length($menuentry);
410
last if $tme eq $menuentry;
412
for ($j=$i; $j<=$#work+1; $j++) {
413
next if $work[$j] =~ m/^\s+\S/;
414
last unless $work[$j] =~ m/^\* *([^:]+): *\((\w[^\)]*)\)/;
415
$tme= $1; $tfile= $2;
416
last unless $tfile eq $target_entry;
417
next if !length($menuentry);
419
last unless $tme eq $menuentry;
423
&dprint("i=$i \$work[\$i]='$work[$i]' j=$j \$work[\$j]='$work[$j]'");
424
printf(_g("%s: deleting entry \`%s ...'")."\n", $name, $match) unless $quiet;
426
unless (m/^\s/ || m/^\*/ || m/^$/ ||
427
$j > $#work || $work[$j] !~ m/^\s*$/) {
430
printf(_g("%s: empty section \`%s' not removed")."\n", $name, $_) unless $quiet;
433
printf(_g("%s: deleting empty section \`%s'")."\n", $name, $_) unless $quiet;
436
@work= (@work[0..$i-1], @work[$j..$#work]);
439
if (length($menuentry)) {
440
printf _g("%s: no entry for file \`%s' and menu entry \`%s'")."\n", $name, $target_entry, $menuentry;
442
printf _g("%s: no entry for file \`%s'")."\n", $name, $target_entry;
450
for ($i=0; $i<=$#work; $i++) {
453
if ( m/^(\* *[^:]+: *\(\w[^\)]*\)[^.]*\.)[ \t]*(.*)/ ) {
454
$length = length($1) if ( length($1) > $length );
456
} elsif ( m/^[ \t]+(.*)/ ) {
457
$work[$j] = "$work[$j] $1";
462
@work = @work[0..$j];
468
if ( m/^(\* *[^:]+: *\(\w[^\)]*\)[^.]*\.)[ \t]*(.*)/ ||
470
if (length $1 >= $descalign) {
472
$_=(" " x $descalign) . $2;
475
$_ = $1 . (" " x ($descalign - length $1)) . $2;
477
push @newwork, split( "\n", wrap('', " " x $descalign, $_ ) );
484
open(NEW,"> $dirfile.new") || &ulquit(sprintf(_g("unable to create %s: %s"),
485
"$dirfile.new", $!));
486
print(NEW @head,join("\n",@newwork)) ||
487
&ulquit(sprintf(_g("unable to write %s: %s"), "$dirfile.new", $!));
488
close(NEW) || &ulquit(sprintf(_g("unable to close %s: %s"), "$dirfile.new", $!));
490
unlink("$dirfile.old");
491
link($dirfile, "$dirfile.old") ||
492
&ulquit(sprintf(_g("unable to backup old %s, giving up: %s"),
494
rename("$dirfile.new", $dirfile) ||
495
&ulquit(sprintf(_g("unable to install new %s: %s"), $dirfile, $!));
497
unlink("$dirfile.lock") ||
498
&quit(sprintf(_g("unable to unlock %s: %s"), $dirfile, $!));
499
system ('cp', $dirfile, $backup) &&
500
warn sprintf(_g("%s: could not backup %s in %s: %s"), $name, $dirfile, $backup, $!)."\n";
509
unlink("$dirfile.lock") ||
510
warn sprintf(_g("%s: warning - unable to unlock %s: %s"),
511
$name, $dirfile, $!)."\n";
516
return if !$pipeit || !$? || $?==0x8D00 || $?==0x0D;
517
&quit(sprintf(_g("unable to read %s: %d"), $filename, $?));
521
printf(DEBUG _g("dbg: %s")."\n", $_[0]) if ($debug);