!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache. PHP/8.1.30 

uname -a: Linux server1.tuhinhossain.com 5.15.0-151-generic #161-Ubuntu SMP Tue Jul 22 14:25:40 UTC
2025 x86_64
 

uid=1002(picotech) gid=1003(picotech) groups=1003(picotech),0(root)  

Safe-mode: OFF (not secure)

/usr/lib/groff/groffer/   drwxr-xr-x
Free 28.67 GB of 117.98 GB (24.3%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     main_subs.pl (57.96 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#! /usr/bin/perl

# groffer - display groff files

# Source file position: <groff-source>/contrib/groffer/subs.pl
# Installed position: <prefix>/lib/groff/groffer/subs.pl

# Copyright (C) 2006-2018 Free Software Foundation, Inc.
# Written by Bernd Warken <groff-bernd.warken-72@web.de>.

# Last update: 27 Aug 2015

# This file is part of 'groffer', which is part of 'groff'.

# 'groff' 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.

# 'groff' 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, see
# <http://www.gnu.org/licenses/gpl-2.0.html>.

########################################################################
# This file contains the main functions formerly in 'groff.pl'

use strict;
use warnings;


########################################################################
# main_set_options()
########################################################################

sub main_set_options {
  our %Opts_Cmdline_Short;
  our %Opts_Cmdline_Long;
  our $Opts_Cmdline_Long_Str;
  our %Opts_Cmdline_Double;
  our %Opts_Groff_Short;

  # the following options are ignored in groffer.pl, but are kept from
  # groffer.sh: --shell arg, --debug-shell

  my @opts_ignored_short_na = ();
  my @opts_ignored_short_arg = ();

  my @opts_ignored_long_na = ('debug-shell');

  my @opts_ignored_long_arg = ('shell');


  ###### groffer native options

  my @opts_groffer_short_na = ('h', 'Q', 'v', 'V', 'X', 'Z');
  my @opts_groffer_short_arg = ('T');

  my @opts_groffer_long_na = ('auto', 'apropos', 'apropos-data',
  'apropos-devel', 'apropos-progs', 'debug', 'debug-all',
  'debug-filenames', 'debug-func', 'debug-grog', 'debug-not-func',
  'debug-keep', 'debug-lm', 'debug-params', 'debug-stacks',
  'debug-tmpdir', 'debug-user', 'default', 'do-nothing', 'dvi',
  'groff', 'help', 'intermediate-output', 'html', 'latin1', 'man',
  'no-location', 'no-man', 'no-special', 'pdf', 'pdf2', 'ps', 'rv',
  'source', 'text', 'to-stdout', 'text-device', 'tty', 'tty-device',
  'utf8', 'version', 'whatis', 'where', 'www', 'x', 'X', 'xhtml');

### main_set_options()
  my @opts_groffer_long_arg =
    ('default-modes', 'device', 'extension', 'fg', 'fn', 'font',
     'foreground', 'mode', 'print', 'title', 'viewer',
     # tty viewers are ignored
     'dvi-viewer-tty', 'html-viewer-tty', 'pdf-viewer-tty',
     'ps-viewer-tty', 'tty-viewer-tty', 'www-viewer-tty',
     'X-viewer-tty', 'x-viewer-tty', 'xhtml-viewer-tty',,
     # viewers for modes are ignored
     'dvi-viewer', 'html-viewer', 'pdf-viewer', 'ps-viewer', 'tty-viewer',
     'www-viewer', 'X-viewer', 'x-viewer', 'xhtml-viewer',
    );

  ##### groffer options inhereted from groff

  my @opts_groff_short_na = ('a', 'b', 'c', 'C', 'e', 'E', 'g', 'G',
  'i', 'j', 'J', 'k', 'l', 'N', 'p', 'R', 's', 'S', 't', 'U', 'z');

  my @opts_groff_short_arg = ('d', 'f', 'F', 'I', 'K', 'L', 'm', 'M', 'n',
  'o', 'P', 'r', 'w', 'W');

  my @opts_groff_long_na = ();
  my @opts_groff_long_arg = ();

  ##### groffer options inhereted from the X Window toolkit

  my @opts_x_short_na = ();
  my @opts_x_short_arg = ();

  my @opts_x_long_na = ('iconic', 'rv');

  my @opts_x_long_arg = ('background', 'bd', 'bg', 'bordercolor',
  'borderwidth', 'bw', 'display', 'fg', 'fn', 'font', 'foreground',
  'ft', 'geometry', 'resolution', 'title', 'xrm');

### main_set_options()
  ###### groffer options inherited from man

  my @opts_man_short_na = ();
  my @opts_man_short_arg = ();

  my @opts_man_long_na = ('all', 'ascii', 'catman', 'ditroff',
  'local-file', 'location', 'troff', 'update');

  my @opts_man_long_arg = ('locale', 'manpath', 'pager',
  'preprocessor', 'prompt', 'sections', 'systems', 'troff-device');

  ###### additional options for parsing evironment variable $MANOPT only

  my @opts_manopt_short_na = ('7', 'a', 'c', 'd', 'D', 'f', 'h', 'k',
  'l', 't', 'u', 'V', 'w', 'Z');

  my @opts_manopt_short_arg = ('e', 'L', 'm', 'M', 'p', 'P', 'r', 'S',
  'T');

  my @opts_manopt_long_na = (@opts_man_long_na, 'apropos', 'debug',
  'default', 'help', 'html', 'ignore-case', 'location-cat',
  'match-case', 'troff', 'update', 'version', 'whatis', 'where',
  'where-cat');

  my @opts_manopt_long_arg = (@opts_man_long_na, 'config_file',
  'encoding', 'extension', 'locale');

### main_set_options()
  ###### collections of command-line options

  # There are two hashes that control the whole of the command-line
  # options, one for short and one for long options.  Options without
  # and with arguments are mixed by advicing a value of 0 for an option
  # without argument and a value of 1 for an option with argument.
  # The options are with leading minus.

  foreach (@opts_groffer_short_na, @opts_groff_short_na,
       @opts_x_short_na, @opts_man_short_na, @opts_ignored_short_na) {
    $Opts_Cmdline_Short{"-$_"} = 0 if $_;
  }
  foreach (@opts_groffer_short_arg, @opts_groff_short_arg,
       @opts_x_short_arg, @opts_man_short_arg, @opts_ignored_short_arg) {
    $Opts_Cmdline_Short{"-$_"} = 1 if $_;
  }

  foreach (@opts_groffer_long_na, @opts_groff_long_na,
       @opts_x_long_na, @opts_man_long_na, @opts_ignored_long_na) {
    $Opts_Cmdline_Long{"--$_"} = 0 if $_;
  }
  foreach (@opts_groffer_long_arg, @opts_groff_long_arg,
       @opts_x_long_arg, @opts_man_long_arg, @opts_ignored_long_arg) {
    $Opts_Cmdline_Long{"--$_"} = 1 if $_;
  }

  # For determining abbreviations of an option take two spaces as join
  # for better check.
  # The options are without leading minus.
  $Opts_Cmdline_Long_Str = join '  ', keys %Opts_Cmdline_Long;
  if ($Opts_Cmdline_Long_Str) {
    $Opts_Cmdline_Long_Str = " $Opts_Cmdline_Long_Str ";
    $Opts_Cmdline_Long_Str =~ s/--//g;
  }

### main_set_options()
  # options with equal meaning are mapped to a single option name
  # all of these have leading minus characters
  %Opts_Cmdline_Double = ('-h' => '--help',
              '-Q' => '--source',
              '-T' => '--device',
              '-v' => '--version',
              '-Z' => '--intermediate-output',
              '--bd' => '--bordercolor',
              '--bg' => '--background',
              '--bw' => '--borderwidth',
              '--debug-all' => '--debug',
              '--ditroff' => '--intermediate-output',
              '--fg' => '--foreground',
              '--fn' => '--font',
              '--ft' => '--font',
              '--latin1' => '--tty',
              '--troff-device' => '--device',
              '--tty-device' => '--text-device',
              '--viewer' => '--viewer',
              '--where' => '--location',
              '--www' => '--html',
              '--X' => '--x',
              '--xhtml' => '--html',
              # '--dvi-viewer' => '--viewer',
              '--dvi-viewer-tty' => '--viewer',
              '--html-viewer-tty' => '--viewer',
              '--xhtml-viewer-tty' => '--pager',
              '--pdf-viewer-tty' => '--viewer',
              '--ps-viewer-tty' => '--viewer',
              '--tty-viewer' => '--pager',
              '--tty-viewer-tty' => '--pager',
              '--www-viewer' => '--viewer',
              '--www-viewer-tty' => '--pager',
              '--X-viewer' => '--viewer', '--X-viewer-tty'
              => '--pager', '--x-viewer' => '--viewer',
              '--x-viewer-tty' => '--pager', );

  # groff short options with leading minus
  foreach (@opts_groff_short_na) {
    $Opts_Groff_Short{"-$_"} = 0;
  }
  foreach (@opts_groff_short_arg) {
    $Opts_Groff_Short{"-$_"} = 1;
  }

} # main_set_options()


########################################################################
# main_parse_MANOPT
########################################################################

sub main_parse_MANOPT {
  our @Manopt;
  our $File_split_env_sh;

  if ( $ENV{'MANOPT'} ) {
    @Manopt = `sh $File_split_env_sh MANOPT`;
    chomp @Manopt;

    my @manopt;
    # %opts stores options that are used by groffer for $MANOPT
    # All options not in %opts are ignored.
    # Check options used with %Opts_Cmdline_Double.
    # 0: option used ('' for ignore), 1: has argument or not
    ### main_parse_MANOPT()
    my %opts = ('-7' => ['--ascii', 0],
        '-L' => ['--locale', 1],
        '-M' => ['--manpath', 1],
        '-P' => ['--pager', 1],
        '-S' => ['--sections', 1],
        '-T' => ['-T', 1],
        '-w' => ['--location', 0],
        '-a' => ['--all', 0],
        '-c' => ['', 1],
        '-e' => ['--extension', 1],
        '-f' => ['--whatis', 1],
        '-m' => ['--systems', 1],
        '-p' => ['', 1],
        '-r' => ['', 1],
        '-manpath' => ['--manpath', 1],
        '-pager' => ['--pager', 1],
        '-prompt' => ['', 1],
        '-sections' => ['--sections', 1],
        '--all' => ['--all', 0],
        '--ascii' => ['--ascii', 0],
        '--catman' => ['', 1],
        '--device' => ['-T', 1],
        '--extension' => ['--extension', 1],
        '--locale' => ['--locale', 1],
        '--location' => ['--location', 0],
        '--manpath' => ['--manpath', 1],
        '--preprocessor' => ['', 1],
        '--systems' => ['--systems', 1],
        '--whatis' => ['--whatis', 1],
        '--where' => ['--location', 0],
           );

### main_parse_MANOPT()
    my ($opt, $has_arg);
    my $i = 0;
    my $n = $#Manopt;
    while ($i <= $n) {
      my $o = $Manopt[$i];
      ++$i;
      # ignore, when not in %opts
      next unless (exists $opts{$o});
      if (($o eq '-D') or ($o eq '--default')) {
    @manopt = ();
    next;
      }
      $opt = $opts{$o}[0];
      $has_arg = $opts{$o}[1];
      # ignore, when empty in %opts
      unless ($opt) {
    # ignore without argument
    next unless ($has_arg);
    # ignore the argument as well
    ++$i;
    next;
      }
      if ($has_arg) {
    last if ($i > $n);
    push @manopt, $opt, $Manopt[$i];
    ++$i;
    next;
      } else {
    push @manopt, $opt;
    next;
      }
    }
    @Manopt = @manopt;
  }
}                # main_parse_MANOPT()


########################################################################
# configuration files, $GROFFER_OPT, and command line, main_config_params()
########################################################################

sub main_config_params {    # handle configuration files
  our @Options;
  our @Filespecs;
  our @Starting_Conf;
  our @Starting_ARGV = @ARGV;

  our %Opts_Cmdline_Short;
  our %Opts_Cmdline_Long;
  our $Opts_Cmdline_Long_Str;
  our %Opts_Cmdline_Double;
  our %Opts_Groff_Short;

  our $File_split_env_sh;
  our @Manopt;
  our @Conf_Files;

  # options may not be abbreviated, but must be exact
  my @conf_args;
  foreach my $f ( @Conf_Files ) {
    if (-s $f) {
      my $fh;
      open $fh, "<$f" || next;
      my $nr = 0;
    LINE: foreach my $line (<$fh>) {
    ++ $nr;
    chomp $line;
    # remove starting and ending whitespace
    $line =~ s/^\s+|\s+$//g;
    # replace whitespace by single space
    $line =~ s/\s+/ /g;
    # ignore all lines that do not start with minus
    next unless $line =~ /^-/;
    # three minus
    if ($line =~ /^---/) {
      warn "Wrong option $line in configuration file $f.\n";
      next;
    }
    if ( $line =~ /^--[ =]/ ) {
      warn "No option name in '$line' in configuration " .
        "file $f.\n";
      next;
    }
    push @Starting_Conf, $line;
    # -- or -
    if ($line =~ /^--?$/) {
      warn "'$line' is not allowed in configuration files.\n";
      next; }
### main_config_params()
    if ($line =~ /^--/) {        # line is long option
      my ($name, $arg);
      if ($line =~ /[ =]/) {    # has arg on line $line =~
        /^(--[^ =]+)[ =] ?(.*)$/;
        ($name, $arg) = ($1, $2);
        $arg =~ s/[\'\"]//g;
      } else {            # does not have an argument on line
        $name = $line;
      } $name =~ s/[\'\"]//g;
      unless (exists $Opts_Cmdline_Long{$name}) {
        # option does not exist
        warn "Option '$name' does not exist.\n";
        next LINE;
      }
      # option exists
      if ( $Opts_Cmdline_Long{$name} ) { # option has arg
        if (defined $arg) {
          push @conf_args, $name, $arg;
          next LINE;
        } else { warn "Option '$name' needs an argument in " .
               "configuration file $f\n";
             next LINE;
           }
      } else { # option has no arg
        if (defined $arg) {
          warn "Option '$name' may not have an argument " .
        "in configuration file $f\n";
          next LINE;
        } else {
          push @conf_args, $name; next LINE;
        }
      }
### main_config_params()
    } else {            # line is short option or cluster
      $line =~ s/^-//;
      while ($line) {
        $line =~ s/^(.)//;
        my $opt = "-$1";
        next if ($opt =~ /\'\"/);
        if ($opt =~ /- /) {
          warn "Option '$conf_args[$#conf_args]' does not " .
        "have an argument.\n";
          next LINE;
        }
        if ( exists $Opts_Cmdline_Short{$opt} ) {
          # short opt exists
          push @conf_args, $opt;
          if ( $Opts_Cmdline_Short{$opt} ) { # with arg
        my $arg = $line;
        $arg =~ s/^ //;
        $arg =~ s/\'\"//g;
        push @conf_args, "$arg";
        next LINE;
          } else { # no arg
        next;
          }
        } else { # short option does not exist
          warn "Wrong short option '-$opt' from " .
        "configuration.  Rest of line ignored.\n";
          next LINE;
        }
      }
    }
      }
      close $fh;
    }
  }

### main_config_params()
  #handle environment variable $GROFFER_OPT
  my @GROFFER_OPT;
  if ( $ENV{'GROFFER_OPT'} ) {
    @GROFFER_OPT = `sh $File_split_env_sh GROFFER_OPT`;
    chomp @GROFFER_OPT;
  }

  # Handle command-line parameters together with $GROFFER_OPT.
  # Options can be abbreviated, with each - as abbreviation place.
  {
    my @argv0 = (@GROFFER_OPT, @ARGV);
    my @argv;
    my $only_files = 0;
    my $n = $#argv0;        # last element
    my $n1 = scalar @GROFFER_OPT; # first element of @ARGV
    my $i = 0;            # number of the element
    my @s = ('the environment variable $GROFFER_OPT', 'the command line');
    my $j = 0;            # index in @s, 0 before $n1, 1 then
  ELT: while ($i <= $n) {
      my $elt = $argv0[$i];
      $j = 1 if $i >= $n1;
      ++$i;
      # remove starting and ending whitespace
      $elt =~ s/^\s+|\s+$//g;
      # replace whitespace by single space
      $elt =~ s/\s+/ /g;

      if ($only_files) {
    push @Filespecs, $elt;
    next ELT;
      }

### main_config_params()
      if ( $elt =~ /^-$/ ) { # -
    push @Filespecs, $elt;
    next ELT;
      }
      if ($elt =~ /^--$/) { # --
    $only_files = 1;
    next ELT;
      }

      if ($elt =~ /^--[ =]/) { # no option name
    warn "No option name in '$elt' at $s[$j].\n";
    next ELT;
      }
      if ($elt =~ /^---/) { # wrong with three minus
    warn "Wrong option '$elt' at $s[$j].\n";
    next ELT;
      }

      if ($elt =~ /^--[^-]/) { # long option
    my ($name, $opt, $abbrev, $arg);
    if ($elt =~ /[ =]/) { # has arg on elt
      $elt =~ /^--([^ =]+)[ =] ?(.*)$/;
      ($name, $arg) = ($1, $2);
      $opt = "--$name";
      $abbrev = $name;
      $arg =~ s/[\'\"]//g;
    } else {        # does not have an argument in the element
      $opt = $name = $elt;
      $name =~ s/^--//;
      $abbrev = $name;
    }
### main_config_params()
    # remove quotes in name
    $name =~ s/[\'\"]//g;
    my $match = $name;
    $match =~ s/-/[^- ]*-/g;
    if ( exists $Opts_Cmdline_Long{$opt} ) {
      # option exists exactly
    } elsif    ( $Opts_Cmdline_Long_Str =~ / (${match}[^- ]*?) / ) {
      # option is an abbreviation without further -
      my $n0 = $1;
      if ( $Opts_Cmdline_Long_Str =~
           /\s(${match}[^-\s]*)\s.*\s(${match}[^-\s]*) / ) {
        warn "Option name '--$abbrev' is not unique: " .
          "--$1 --$2 \n";
        next ELT;
      }
      $name = $n0;
      $opt = "--$n0";
    } elsif ( $Opts_Cmdline_Long_Str =~ /\s(${match}[^\s]*)\s/ ) {
      # option is an abbreviation with further -
      my $n0 = $1;
      if ( $Opts_Cmdline_Long_Str =~
           /\s(${match}[^\s]*)\s.*\s(${match}[^\s]*)\s/ ) {
        warn "Option name '--$abbrev' is not unique: " .
          "--$1 --$2 \n";
        next ELT;
      }
      $name = $n0;
      $opt = "--$n0";
    } else {
      warn "Option '--$abbrev' does not exist.\n";
      next ELT;
    }
### main_config_params()
    if ( $Opts_Cmdline_Long{$opt} ) { # option has arg
      if (defined $arg) {
        push @argv, "--$name", $arg;
        next ELT;
      } else { # $arg not defined, argument at next    element
        if (($i == $n1) || ($i > $n)) {
          warn "No argument left for option " .
        "'$elt' at $s[$j].\n";
          next ELT; }
        # add argument as next element
        push @argv, "--$name", $argv0[$i];
        ++$i;
        next ELT;
      }        # if (defined $arg)
    } else {    # option has no arg
      if (defined $arg) {
        warn "Option '$abbrev' may not have an argument " .
          "at $s[$j].\n";
        next ELT;
      } else {
        push @argv, "--$name";
        next ELT;
      }
    }        # if ($Opts_Cmdline_Long{$opt})
### main_config_params()
      } elsif ( $elt =~ /^-[^-]/ ) { # short option or cluster
    my $cluster = $elt;
    $cluster =~ s/^-//;
    while ($cluster) {
      $cluster =~ s/^(.)//;
      my $opt = "-$1";
      if ( exists $Opts_Cmdline_Short{$opt} ) {    # opt exists
        if ( $Opts_Cmdline_Short{$opt} ) {        # with arg
          if ($cluster) {    # has argument in this element
        $cluster =~ s/^\s//;
        $cluster =~ s/\'\"//g;
        # add argument as rest of this element
        push @argv, $opt, $cluster;
        next ELT;
          } else { # argument at next element
        if (($i == $n1) || ($i > $n)) {
          warn "No argument left for option " .
            "'$opt' at $s[$j].\n";
          next ELT; }
### main_config_params()
        # add argument as next element
        push @argv, $opt, $argv0[$i];
        ++$i;
        next ELT;
          }
        } else { # no arg
          push @argv, $opt; next;
        }
      } else { # short option does not exist
        warn "Wrong short option '$opt' at $s[$j].\n";
        next ELT;
      }        # if (exists $Opts_Cmdline_Short{$opt})
    }        # while ($cluster)
      } else {        # not an option, file name
    push @Filespecs, $elt;
    next;
      }
    }
### main_config_params()
    @Options = (@Manopt, @conf_args, @argv);
    foreach my $i ( 0..$#Options ) {
      if ( exists $Opts_Cmdline_Double{$Options[$i]} ) {
    $Options[$i] = $Opts_Cmdline_Double{ $Options[$i] };
      }
    } @Filespecs = ('-') unless (@Filespecs);
    @ARGV = (@Options, '--', @Filespecs);
  }
} # main_config_params()


########################################################################
# main_parse_params()
########################################################################

sub main_parse_params {
  # options that are ignored in this part
  # shell version of groffer: --debug*, --shell
  # man options: --catman (only special in man),
  #         --preprocessor (force groff preproc., handled by grog),
  #         --prompt (prompt for less, ignored),
  #         --troff (-mandoc, handled by grog),
  #         --update (inode check, ignored)
  our %Opt;
  our %Man;
  our %Debug;
  our %Opts_Cmdline_Short;
  our %Opts_Cmdline_Double;
  our %Opts_Cmdline_Long;
  our %Opts_Groff_Short;
  our $i;
  our $n;
  our @Starting_ARGV;
  our @Starting_Conf;
  our @Default_Modes;
  our @Addopts_Groff;
  our @Options;

  my %ignored_opts = (
              '--catman' => 0,
              '--debug-func' => 0,
              '--debug-not-func' => 0,
              '--debug-lm' => 0,
              '--debug-shell' => 0,
              '--debug-stacks' => 0,
              '--debug-user' => 0,
              '--preprocessor' => 1,
              '--prompt' => 1,
              '--shell' => 1,
              '--troff' => 0,
              '--update' => 0,
             );

### main_parse_params()
  my %long_opts =
    (
     '--debug' =>
     sub { $Debug{$_} = 1 foreach (qw/FILENAMES GROG KEEP PARAMS TMPDIR/); },
     '--debug-filenames' => sub { $Debug{'FILENAMES'} = 1; },
     '--debug-grog' => sub { $Debug{'GROG'} = 1; },
     '--debug-keep' => sub { $Debug{'KEEP'} = 1; $Debug{'PARAMS'} = 1; },
     '--debug-params' => sub { $Debug{'PARAMS'} = 1; },
     '--debug-tmpdir' => sub { $Debug{'TMPDIR'} = 1; },
     '--help' => sub { &usage(); $Opt{'DO_NOTHING'} = 1; },
     '--source' => sub { $Opt{'MODE'} = 'source'; },
     '--device' =>
     sub { $Opt{'DEVICE'} = &_get_arg();
       my %modes = (
            'ascii' => 'tty',
            'cp1047' => 'tty',
            'dvi'=> 'dvi',
            'html' => 'html',
            'xhtml' => 'html',
            'latin1' => 'tty',
            'lbp' => 'groff',
            'lj4' => 'groff',
            'pdf' => 'pdf',
            'pdf2' => 'pdf2',
            'ps' => 'ps',
            'utf8' => 'tty',
               );
        if ($Opt{'DEVICE'} =~ /^X.*/) {
          $Opt{'MODE'} = 'x';
        } elsif ( exists $modes{ $Opt{'DEVICE'} } ) {
          if ( $modes{ $Opt{'DEVICE'} } eq 'tty' ) {
        $Opt{'MODE'} = 'tty'
          unless ($Opt{'MODE'} eq 'text');
          } else {
        $Opt{'MODE'} = $modes{ $Opt{'DEVICE'} };
          }
        } else {
          # for all elements not in %modes
          $Opt{'MODE'} = 'groff';
        }
      },
### main_parse_params()
     '--version' => sub { &version(); $Opt{'DO_NOTHING'} = 1; },
     '--intermediate-output' => sub { $Opt{'Z'} = 1; },
     '--all' => sub { $Opt{'ALL'} = 1; },
     '--apropos' =>        # run apropos
     sub { $Opt{'APROPOS'} = 1;
       delete $Opt{'APROPOS_SECTIONS'};
       delete $Opt{'WHATIS'}; },
     '--apropos-data' =>    # run apropos for data sections
     sub { $Opt{'APROPOS'} = 1;
       $Opt{'APROPOS_SECTIONS'} = '457';
       delete $Opt{'WHATIS'}; },
     '--apropos-devel' =>    # run apropos for devel sections
     sub { $Opt{'APROPOS'} = 1;
       $Opt{'APROPOS_SECTIONS'} = '239';
       delete $Opt{'WHATIS'}; },
     '--apropos-progs' =>    # run apropos for prog sections
     sub { $Opt{'APROPOS'} = 1;
       $Opt{'APROPOS_SECTIONS'} = '168';
       delete $Opt{'WHATIS'}; },
     '--ascii' =>
     sub { push @Addopts_Groff, '-mtty-char';
       $Opt{'MODE'} = 'text' unless $Opt{'MODE'}; },
     '--auto' =>        # the default automatic mode
     sub { delete $Opt{'MODE'}; },
     '--bordercolor' =>        # border color for viewers, arg
     sub { $Opt{'BD'} = &_get_arg(); },
     '--background' =>        # background color for viewers, arg
     sub { $Opt{'BG'} = &_get_arg(); },
### main_parse_params()
     '--borderwidth' =>        # border width for viewers, arg
     sub { $Opt{'BW'} = &_get_arg(); },
     '--default' =>        # reset variables to default
     sub { %Opt = (); },
     '--default-modes' =>    # sequence of modes in auto mode; arg
     sub { $Opt{'DEFAULT_MODES'} = &_get_arg(); },
     '--display' =>        # set X display, arg
     sub { $Opt{'DISPLAY'} = &_get_arg(); },
     '--do-nothing' => sub { $Opt{'DO_NOTHING'} = 1; },
     '--dvi' => sub { $Opt{'MODE'} = 'dvi'; },
     '--extension' =>        # the extension for man pages, arg
     sub { $Opt{'EXTENSION'} = &_get_arg(); },
     '--foreground' =>        # foreground color for viewers, arg
     sub { $Opt{'FG'} = &_get_arg(); },
     '--font' =>        # set font for viewers, arg
     sub { $Opt{'FN'} = &_get_arg(); },
     '--geometry' =>        # window geometry for viewers, arg
     sub { $Opt{'GEOMETRY'} = &_get_arg(); },
     '--groff' => sub { $Opt{'MODE'} = 'groff'; },
     '--html' => sub { $Opt{'MODE'} = 'html'; },
     '--iconic' =>        # start viewers as icons
     sub { $Opt{'ICONIC'} = 1; },
     '--locale' =>        # set language for man pages, arg
     # argument is xx[_territory[.codeset[@modifier]]] (ISO 639,...)
     sub { $Opt{'LANG'} = &_get_arg(); },
     '--local-file' =>        # force local files; same as '--no-man'
     sub { delete $Man{'ENABLE'}; delete $Man{'FORCE'}; },
     '--location' =>        # print file locations to stderr
     sub { $Opt{'LOCATION'} = 1; },
### main_parse_params()
     '--man' =>            # force all file params to be man pages
     sub { $Man{'ENABLE'} = 1; $Man{'FORCE'} = 1; },
     '--manpath' =>        # specify search path for man pages, arg
     # arg is colon-separated list of directories
     sub { $Opt{'MANPATH'} = &_get_arg(); },
     '--mode' =>        # display mode
     sub { my $arg = &_get_arg();
       my %modes = ( '' => '',
             'auto' => '',
             'groff' => 'groff',
             'html' => 'html',
             'www' => 'html',
             'dvi' => 'dvi',
             'pdf' => 'pdf',
             'pdf2' => 'pdf2',
             'ps' => 'ps',
             'text' => 'text',
             'tty' => 'tty',
             'X' => 'x',
             'x' => 'x',
             'Q' => 'source',
             'source' => 'source',
               );
       if ( exists $modes{$arg} ) {
         if ( $modes{$arg} ) {
           $Opt{'MODE'} = $modes{$arg};
         } else {
           delete $Opt{'MODE'};
         }
       } else {
         warn "Unknown mode in '$arg' for --mode\n";
       }
     },
### main_parse_params()
     '--no-location' =>        # disable former call to '--location'
     sub { delete $Opt{'LOCATION'}; },
     '--no-man' =>        # disable search for man pages
     sub { delete $Man{'ENABLE'}; delete $Man{'FORCE'}; },
     '--no-special' =>        # disable some special former calls
     sub { delete $Opt{'ALL'}; delete $Opt{'APROPOS'};
       delete $Opt{'WHATIS'}; },
     '--pager' =>        # set paging program for tty mode, arg
     sub { $Opt{'PAGER'} = &_get_arg(); },
     '--pdf' => sub { $Opt{'MODE'} = 'pdf'; },
     '--pdf2' => sub { $Opt{'MODE'} = 'pdf2'; },
     '--print' =>        # print argument, for argument test
     sub { my $arg = &_get_arg; print STDERR $arg . "\n"; },
     '--ps' => sub { $Opt{'MODE'} = 'ps'; },
     '--resolution' =>        # set resolution for X devices, arg
     sub { my $arg = &_get_arg();
       my %res = ( '75' => 75,
               '75dpi' => 75,
               '100' => 100,
               '100dpi' => 100,
             );
       if (exists $res{$arg}) {
         $Opt{'RESOLUTION'} = $res{$arg};
       } else {
         warn "--resolution allows only 75, 75dpi, " .
           "100, 100dpi as argument.\n";
       }
     },
### main_parse_params()
     '--rv' => sub { $Opt{'RV'} = 1; },
     '--sections' =>        # specify sections for man pages, arg
     # arg is a ':'-separated (colon) list of section names
     sub { my $arg = &_get_arg();
       my @arg = split /:/, $arg;
       my $s;
       foreach (@arg) {
         /^(.)/;
         my $c = $1;
         if ($Man{'AUTO_SEC_CHARS'} =~ /$c/) {
           $s .= $c;
         } else {
           warn "main_parse_params(): not a man section '$c';";
         }
       }
       $Opt{'SECTIONS'} = $s; },
     '--systems' =>        # man pages for different OS's, arg
     # argument is a comma-separated list
     sub { $Opt{'SYSTEMS'} = &_get_arg(); },
     '--text' =>        # text mode without pager
     sub { $Opt{'MODE'} = 'text'; },
     '--title' =>        # title for X viewers; arg
     sub { my $arg = &_get_arg();
       if ($arg) {
         if ( $Opt{'TITLE'} ) {
           $Opt{'TITLE'} = "$Opt{'TITLE'} $arg";
         } else {
           $Opt{'TITLE'} = $arg;
         }
       }
     },
     '--text-device' =>        # device for tty mode; arg
     sub { $Opt{'TEXT_DEVICE'} = &_get_arg(); },
     '--to-stdout' =>        # print mode file without display
     sub { $Opt{'STDOUT'} = 1; },
     '--tty' =>            # tty mode, text with pager
     sub { $Opt{'MODE'} = 'tty'; },
     '--viewer' =>        # viewer for actiual mode
     sub { $Opt{'VIEWER'} = &_get_arg(); },
     '--whatis' => sub { delete $Opt{'APROPOS'}; $Opt{'WHATIS'} = 1; },
     '--x' => sub { $Opt{'MODE'} = 'x'; },
### main_parse_params()
     '--xrm' =>            # pass X resource string, arg
     sub { my $arg = &_get_arg(); push @{$Opt{'XRM'}}, $arg if $arg; },
    );

#     '--dvi-viewer' =>        # viewer program for dvi mode; arg
#     sub { $Opt{'VIEWER_DVI'} = &_get_arg(); },
#     '--html-viewer' =>        # viewer program for html mode; arg
#     sub { $Opt{'VIEWER_HTML'} = &_get_arg(); },
#     '--pdf-viewer' =>        # viewer program for pdf and pdf2 mode; arg
#     sub { $Opt{'VIEWER_PDF'} = &_get_arg(); },
#     '--ps-viewer' =>        # viewer program for ps mode; arg
#     sub { $Opt{'VIEWER_PS'} = &_get_arg(); },
#     '--x-viewer' =>        # viewer program for x mode; arg
#     sub { $Opt{'VIEWER_X'} = &_get_arg(); },

  my %short_opts = (
            '-V' => sub { $Opt{'V'} = 1; },
            '-X' => sub { $Opt{'X'} = 1; },
           );

  if (0) {
    # check if all options are handled in parse parameters

    # short options
    my %these_opts = (%ignored_opts, %short_opts, %Opts_Groff_Short,
              %Opts_Cmdline_Double);
    foreach my $key (keys %Opts_Cmdline_Short) {
      warn "unused option: $key" unless exists $these_opts{$key};
    }

    # long options
    %these_opts = (%ignored_opts, %long_opts, %Opts_Cmdline_Double);
    foreach my $key (keys %Opts_Cmdline_Long) {
      warn "unused option: $key" unless exists $these_opts{$key};
    }
  }                # if (0)

### main_parse_params()
 OPTION: while ($i <= $n) {
    my $opt = $Options[$i];
    ++$i;
    if ($opt =~ /^-([^-])$/) {    # single minus for short option
      if (exists $short_opts{$opt}) { # short option handled by hash
    $short_opts{$opt}->();
    next OPTION;
      } else {            # $short_opts{$opt} does not exist
    my $c = $1;        # the option character
    next OPTION unless $c;
    if ( exists $Opts_Groff_Short{ $opt } ) { # groff short option
      if ( $Opts_Groff_Short{ $opt } ) { # option has argument
        my $arg = $Options[$i];
        ++$i;
        push @Addopts_Groff, $opt, $arg;
        next OPTION;
      } else {        # no argument for this option
        push @Addopts_Groff, $opt;
        next OPTION;
      }
    } elsif ( exists $Opts_Cmdline_Short{ $opt } ) {
      # is a groffer short option
      warn "Groffer option $opt not handled " .
        "in parameter parsing";
    } else {
      warn "$opt is not a groffer option.\n";
    }
      }                # if (exists $short_opts{$opt})
    }                # if ($opt =~ /^-([^-])$/)
    # now it is a long option

    # handle ignored options
    if ( exists $ignored_opts{ $opt } ) {
      ++$i if ( $ignored_opts{ $opt } );
      next OPTION;
    }
### main_parse_params()

    # handle normal long options
    if (exists $long_opts{$opt}) {
      $long_opts{$opt}->();
    } else {
      warn "Unknown option $opt.\n";
    }
    next OPTION;
  }                # while ($i <= $n)

  if ($Debug{'PARAMS'}) {
    print STDERR '$MANOPT: ' . $ENV{'MANOPT'} . "\n" if $ENV{'MANOPT'};
    foreach (@Starting_Conf) {
      print STDERR "configuration: " . $_ . "\n";
    }
    print STDERR '$GROFFER_OPT: ' . $ENV{'GROFFER_OPT'} . "\n"
      if $ENV{'GROFFER_OPT'};
    print STDERR "command line: @Starting_ARGV\n";
    print STDERR "parameters: @ARGV\n";
  }

  if ( $Opt{'WHATIS'} ) {
    die "main_parse_params(): cannot handle both 'whatis' and 'apropos';"
      if $Opt{'APROPOS'};
    $Man{'ALL'} = 1;
    delete $Opt{'APROPOS_SECTIONS'};
  }

  if ( $Opt{'DO_NOTHING'} ) {
    exit;
  }

  if ( $Opt{'DEFAULT_MODES'} ) {
    @Default_Modes = split /,/, $Opt{'DEFAULT_MODES'};
  }
}                # main_parse_params()


sub _get_arg {
  our $i;
  our $n;
  our @Options;
  if ($i > $n) {
    die '_get_arg(): No argument left for last option;';
  }
  my $arg = $Options[$i];
  ++$i;
  $arg;
}                # _get_arg() of main_parse_params()


########################################################################
# main_set_mode()
########################################################################

sub main_set_mode {
  our %Opt;

  our @Default_Modes;
  our @Addopts_Groff;

  our $Viewer_Background;
  our $PDF_Did_Not_Work;
  our $PDF_Has_gs;
  our $PDF_Has_ps2pdf;
  our %Display = ('MODE' => '',
          'PROG' => '',
          'ARGS' => ''
         );

  my @modes;

  # set display
  $ENV{'DISPLAY'} = $Opt{'DISPLAY'} if $Opt{'DISPLAY'};

  push @Addopts_Groff, '-V' if $Opt{'V'};

  if ( $Opt{'X'} ) {
    $Display{'MODE'} = 'groff';
    push @Addopts_Groff, '-X';
  }

  if ( $Opt{'Z'} ) {
    $Display{'MODE'} = 'groff';
    push @Addopts_Groff, '-Z';
  }

  $Display{'MODE'} = 'groff' if $Opt{'MODE'} and $Opt{'MODE'} eq 'groff';

  return 1 if $Display{'MODE'} and $Display{'MODE'} eq 'groff';

### main_set_mode()
  if ($Opt{'MODE'}) {
    if ($Opt{'MODE'} =~ /^(source|text|tty)$/) {
      $Display{'MODE'} = $Opt{'MODE'};
      return 1;
    }
    $Display{'MODE'} = $Opt{'MODE'} if $Opt{'MODE'} =~ /^x?html$/;
    @modes = ($Opt{'MODE'});
  } else {            # empty mode
    if ($Opt{'DEVICE'}) {
      if ($Opt{'DEVICE'} =~ /^X/) {
    &is_X() || die "no X display found for device $Opt{'DEVICE'}";
    $Display{'MODE'} = 'x';
    return 1;
      }
      ;
      if ($Opt{'DEVICE'} =~ /^(ascii|cp1047|latin1|utf8)$/) {
    $Display{'MODE'} ne 'text' and $Display{'MODE'} = 'tty';
    return 1;
      }
      ;
      unless (&is_X) {
    $Display{'MODE'} = 'tty';
    return 1;
      }
    }                # check device
    @modes = @Default_Modes;
  }                # check mode

### main_set_mode()
 LOOP: foreach my $m (@modes) {
    $Viewer_Background = 0;
    if ($m =~ /^(test|tty|X)$/) {
      $Display{'MODE'} = $m;
      return 1;
    } elsif ($m eq 'pdf') {
      &_get_prog_args($m) ? return 1: next LOOP;
    } elsif ($m eq 'pdf2') {
      next LOOP if $PDF_Did_Not_Work;
      $PDF_Has_gs = &where_is_prog('gs') ? 1 : 0
    unless (defined $PDF_Has_gs);
      $PDF_Has_ps2pdf = &where_is_prog('ps2pdf') ? 1 : 0
    unless (defined $PDF_Has_ps2pdf);
      if ( (! $PDF_Has_gs) and (! $PDF_Has_ps2pdf) ) {
    $PDF_Did_Not_Work = 1;
    next LOOP;
      }

      if (&_get_prog_args($m)) {
    return 1;
      } else {
    $PDF_Did_Not_Work = 1;
    next LOOP;
      }
    } else {            # other modes
      &_get_prog_args($m) ? return 1 : next LOOP;
    }                # if $m
  }                # loop: foreach
  die 'set mode: no suitable display mode found under ' .
    join(', ', @modes) . ';' unless $Display{'MODE'};
  die 'set mode: no viewer available for mode ' . $Display{'MODE'} . ';'
    unless $Display{'PROG'};
  0;
} # main_set_mode()


########################################################################
# functions to main_set_mode()
########################################################################

##########
# _get_prog_args(<MODE>)
#
# Simplification for loop in set mode.
#
# Globals in/out: $Viewer_Background
# globals in    : $Opt{VIEWER}, $VIEWER_X{<MODE>},
#                 $Viewer_tty{<MODE>}
#
## globals in    : $Opt{VIEWER_<MODE>}, $VIEWER_X{<MODE>},
##                 $Viewer_tty{<MODE>}
##
sub _get_prog_args {
  our %Opt;
  our %Display;
  our %Viewer_X;
  our %Viewer_tty;

  our $Viewer_Background;
  my $n = @_;
  die "_get_prog_args(): one argument is needed; you used $n;"
    unless $n == 1;

  my $mode = lc($_[0]);
  my $MODE = uc($mode);
  $MODE = 'PDF' if ( $MODE =~ /^PDF2$/ );

  my $xlist = $Viewer_X{$MODE};
  my $ttylist = $Viewer_tty{$MODE};

#  my $vm = "VIEWER_${MODE";
  my $vm = "VIEWER";
  my $opt = $Opt{$vm};

  if ($opt) {
    my %prog = &where_is_prog($opt);
    my $prog_ref = \%prog;
    unless (%prog) {
      warn "_get_prog_args(): '$opt' is not an existing program;";
      return 0;
    }

    # $prog from $opt is an existing program

### _get_prog_args() of main_set_mode()
    if (&is_X) {
      if ( &_check_prog_on_list($prog_ref, $xlist) ) {
    $Viewer_Background = 1;
      } else {
    $Viewer_Background = 0;
    &_check_prog_on_list($prog_ref, $ttylist);
      }
    } else {            # is not X
      $Viewer_Background = 0;
      &_check_prog_on_list($prog_ref, $ttylist);
    }                # if is X
  } else {            # $opt is empty
    $Viewer_Background = 0;
    my $x;
    if (&is_X) {
      $x = &_get_first_prog($xlist);
      $Viewer_Background = 1 if $x;
    } else {            # is not X
      $x = &_get_first_prog($ttylist);
    }                # test on X
    $Display{'MODE'} = $mode if $x;
    return $x;
  }
  $Display{'MODE'} = $mode;
  return 1;
} # _get_prog_args() of main_set_mode()


##########
# _get_first_prog(<prog_list_ref>)
#
# Retrieve from the elements of the list in the argument the first
# existing program in $PATH.
#
# Local function of main_set_mode().
#
# Return  : '0' if not a part of the list, '1' if found in the list.
#
sub _get_first_prog {
  our %Display;
  my $n = @_;
  die "_get_first_prog(): one argument is needed; you used $n;"
    unless $n == 1;

  foreach my $i (@{$_[0]}) {
    next unless $i;
    my %prog = &where_is_prog($i);
    if (%prog) {
      $Display{'PROG'} = $prog{'fullname'};
      $Display{'ARGS'} = $prog{'args'};
      return 1;
    }
  }
  return 0;
} # _get_first_prog() of main_set_mode()


##########
# _check_prog_on_list (<prog-hash-ref> <prog_list_ref>)
#
# Check whether the content of <prog-hash-ref> is in the list
# <prog_list_ref>.
# The globals are set correspondingly.
#
# Local function for main_set_mode().
#
# Arguments: 2
#
# Return  : '0' if not a part of the list, '1' if found in the list.
# Output  : none
#
# Globals in    : $Viewer_X{<MODE>}, $Viewer_tty{<MODE>}
# Globals in/out: $Display{'PROG'}, $Display{'ARGS'}
#
sub _check_prog_on_list {
  our %Display;
  my $n = @_;
  die "_get_first_prog(): 2 arguments are needed; you used $n;"
    unless $n == 2;

  my %prog = %{$_[0]};

  $Display{'PROG'} = $prog{'fullname'};
  $Display{'ARGS'} = $prog{'args'};

  foreach my $i (@{$_[1]}) {
    my %p = &where_is_prog($i);
    next unless %p;
    next unless $Display{'PROG'} eq $p{'fullname'};
    if ($p{'args'}) {
      if ($Display{'ARGS'}) {
    $Display{'ARGS'} = $p{'args'};
      } else {
    $Display{'ARGS'} = "$p{'args'} $Display{'ARGS'}";
      }
    }                # if args
    return 1;
  }                # foreach $i
  # prog was not in the list
  return 0;
} # _check_prog_on_list() of main_set_mode()


########################################################################
# groffer temporary directory, main_temp()
########################################################################

sub main_temp {
  our %Debug;
  our $tmpdir;
  our $fh_cat;
  our $fh_stdin;
  our $tmp_cat;
  our $tmp_stdin;
  my $template = 'groffer_' . "$$" . '_XXXX';
  foreach ($ENV{'GROFF_TMPDIR'}, $ENV{'TMPDIR'}, $ENV{'TMP'}, $ENV{'TEMP'},
       $ENV{'TEMPDIR'}, File::Spec->catfile($ENV{'HOME'}, 'tmp')) {
    if ($_ && -d $_ && -w $_) {
      if ($Debug{'KEEP'}) {
    eval { $tmpdir = tempdir( $template, DIR => "$_" ); };
      } else {
    eval { $tmpdir = tempdir( $template,
                  CLEANUP => 1, DIR => "$_" ); };
      }
      last if $tmpdir;
    }
  }
  $tmpdir = tempdir( $template, CLEANUP => 1, DIR => File::Spec->tmpdir )
    unless ($tmpdir);

  # see Lerning Perl, page 205, or Programming Perl, page 413
  # $SIG{'INT'} is for Ctrl-C interruption
  $SIG{'INT'} = sub { &clean_up(); die "interrupted..."; };
  $SIG{'QUIT'} = sub { &clean_up(); die "quit..."; };

  if ($Debug{'TMPDIR'}) {
    if ( $Debug{'KEEP'}) {
      print STDERR "temporary directory is kept: " . $tmpdir . "\n";
    } else {
      print STDERR "temporary directory will be cleaned: " .
    $tmpdir . "\n";
    }
  }

  # further argument: SUFFIX => '.sh'
  if ($Debug{'KEEP'}) {
    ($fh_cat, $tmp_cat) = tempfile(',cat_XXXX', DIR => $tmpdir);
    ($fh_stdin, $tmp_stdin) = tempfile(',stdin_XXXX', DIR => $tmpdir);
  } else {
    ($fh_cat, $tmp_cat) = tempfile(',cat_XXXX', UNLINK => 1,
                   DIR => $tmpdir);
    ($fh_stdin, $tmp_stdin) = tempfile(',stdin_XXXX', UNLINK => 1,
                       DIR => $tmpdir);
  }
}                # main_temp()


########################################################################
# subs needed for main_do_fileargs()
########################################################################

##########
# register_file(<filename>)
#
# Write a found file and register the title element.
#
# Arguments: 1: a file name
# Output: none
#
sub register_file {
  our $tmp_stdin;
  my $n = @_;
  die "register_file(): one argument is needed; you used $n;"
    unless $n == 1;
  die 'register_file(): file name is empty;' unless $_[0];

  if ($_[0] eq '-') {
    &to_tmp($tmp_stdin) && &register_title('stdin');
  } else {
    &to_tmp($_[0]) && &register_title($_[0]);
  }
  1;
}                # register_file()


##########
# register_title(<filespec>)
#
# Create title element from <filespec> and append to $_REG_TITLE_LIST.
# Basename is created.
#
# Globals in/out: @REG_TITLE
#
# Variable prefix: rt
#
sub register_title {
  our @REG_TITLE;
  our %Debug;
  my $n = @_;
  die "register_title(): one argument is needed; you used $n;"
    unless $n == 1;
  return 1 unless $_[0];

  return 1 if scalar @REG_TITLE > 3;

  my $title = &get_filename($_[0]);
  $title =~ s/\s/_/g;
  $title =~ s/\.bz2$//g;
  $title =~ s/\.gz$//g;
  $title =~ s/\.Z$//g;

  if ($Debug{'FILENAMES'}) {
    if ($_[0] eq 'stdin') {
      print STDERR "register_title(): file title is stdin\n";
    } else {
      print STDERR "register_title(): file title is $title\n";
    }
  }                # if ($Debug{'FILENAMES'})

  return 1 unless $title;
  push @REG_TITLE, $title;
  1;
}                # register_title()


##########
# save_stdin()
#
# Store standard input to temporary file (with decompression).
#
sub save_stdin {
  our $tmp_stdin;
  our $fh_stdin;
  our $tmpdir;

  our %Debug;

  my ($fh_input, $tmp_input);
  $tmp_input = File::Spec->catfile($tmpdir, ',input');
  open $fh_input, ">$tmp_input" or
    die "save_stdin(): could not open $tmp_input";
  foreach (<STDIN>) {
    print $fh_input $_;
  }
  close $fh_input;
  open $fh_stdin, ">$tmp_stdin" or
    die "save_stdin(): could not open $tmp_stdin";
  foreach ( &cat_z("$tmp_input") ) {
    print $fh_stdin $_;
  }
  close $fh_stdin;
  unlink $tmp_input unless $Debug{'KEEP'};
}    # save_stdin()


########################################################################
# main_do_fileargs()
########################################################################

sub main_do_fileargs {
  our %Man;
  our %Opt;

  our @Filespecs;

  our $Filespec_Arg;
  our $Filespec_Is_Man;
  our $Special_Filespec;
  our $No_Filespecs;
  our $Macro_Pkg;
  our $Manspec;

  &special_setup();
  if ($Opt{'APROPOS'}) {
    if ($No_Filespecs) {
      &apropos_filespec();
      return 1;
    }
  } else {
    foreach (@Filespecs) {
      if (/^-$/) {
    &save_stdin();
    last;
      }
    }                # foreach (@Filespecs)
  }                # if ($Opt{'APROPOS'})

  my $section = '';
  my $ext = '';
  my $twoargs = 0;
  my $filespec;
  my $former_arg;

 FILESPEC: foreach (@Filespecs) {
    $filespec = $_;
    $Filespec_Arg = $_;
    $Filespec_Is_Man = 0;
    $Manspec = '';
    $Special_Filespec = 0;

    next FILESPEC unless $filespec;

### main_do_fileargs()
    if ($twoargs) {        # second run
      $twoargs = 0;
      # $section and $ext are kept from earlier run
      my $h = { 'name' => $filespec, 'sec' => $section, 'ext' => $ext };
      &man_setup();
      if ( &is_man($h) ) {
    $Filespec_Arg = "$former_arg $Filespec_Arg";
    &special_filespec();
    $Filespec_Is_Man = 1;
    &man_get($h);
    next FILESPEC;
      } else {
    warn "main_do_fileargs(): $former_arg is neither a file nor a " .
      "man page nor a section argument for $filespec;";
      }
    }
    $twoargs = 0;

    if ( $Opt{'APROPOS'} ) {
      &apropos_filespec();
      next FILESPEC;
    }

    if ($filespec eq '-') {
      &register_file('-');
      &special_filespec();
      next FILESPEC;
    } elsif ( &get_filename($filespec) ne $filespec ) { # path with dir
      &special_filespec();
      if (-f $filespec && -r $filespec) {
    &register_file($filespec)
      } else {
    warn "main_do_fileargs: the argument $filespec is not a file;";
      }
      next FILESPEC;
    } else {            # neither '-' nor has dir
      # check whether filespec is an existing file
      unless ( $Man{'FORCE'} ) {
    if (-f $filespec && -r $filespec) {
      &special_filespec();
      &register_file($filespec);
      next FILESPEC;
    }
      }
    }                # if ($filespec eq '-')

### main_do_fileargs()
    # now it must be a man page pattern

    if ($Macro_Pkg and $Macro_Pkg ne '-man') {
      warn "main_do_fileargs(): $filespec is not a file, " .
    "man pages are ignored due to $Macro_Pkg;";
      next FILESPEC;
    }

    # check for man page
    &man_setup();
    unless ( $Man{'ENABLE'} ) {
      warn "main_do_fileargs(): the argument $filespec is not a file;";
      next FILESPEC;
    }
    my $errmsg;
    if ( $Man{'FORCE'} ) {
      $errmsg = 'is not a man page';
    } else {
      $errmsg = 'is neither a file nor a man page';
    }

    $Filespec_Is_Man = 1;

### main_do_fileargs()
    # test filespec with 'man:...' or '...(...)' on man page

    my @names = ($filespec);
    if ($filespec =~ /^man:(.*)$/) {
      push @names, $1;
    }

    foreach my $i (@names) {
      next unless $i;
      my $h = { 'name' => $i };
      if ( &is_man($h) ) {
    &special_filespec();
    &man_get($h);
    next FILESPEC;
      }
      if ( $i =~ /^(.*)\(([$Man{'AUTO_SEC_CHARS'}])(.*)\)$/ ) {
    $h = { 'name' => $1, 'sec' => $2, 'ext' => $3 };
    if ( &is_man($h) ) {
      &special_filespec();
      &man_get($h);
      next FILESPEC;
    }
      }                # if //
      if ( $i =~ /^(.*)\.([$Man{'AUTO_SEC_CHARS'}])(.*)$/ ) {
    $h = { 'name' => $1, 'sec' => $2, 'ext' => $3 };
    if ( &is_man($h) ) {
      &special_filespec();
      &man_get($h);
      next FILESPEC;
    }
      }                # if //
    }                # foreach (@names)

### main_do_fileargs()
    # check on "s name", where "s" is a section with or without an extension
    if ($filespec =~ /^([$Man{'AUTO_SEC_CHARS'}])(.*)$/) {
      unless ( $Man{'ENABLE'} ) {
    warn "main_do_fileargs(): $filespec $errmsg;";
    next FILESPEC;
      }
      $twoargs = 1;
      $section = $1;
      $ext = $2;
      $former_arg = $filespec;
      next FILESPEC;
    } else {
      warn "main_do_fileargs(): $filespec $errmsg;";
      next FILESPEC;
    }
  }    # foreach (@Filespecs)

  if ( $twoargs ) {
    warn "main_do_fileargs(): no filespec arguments left for second run;";
    return 0;
  }
  1;
}    # main_do_fileargs()


########################################################################
# main_set_resources()
########################################################################

##########
# main_set_resources ()
#
# Determine options for setting X resources with $_DISPLAY_PROG.
#
# Globals: $Display{PROG}, $Output_File_Name
#
sub main_set_resources {
  our %Opt;
  our %Display;
  our %Debug;

  our @REG_TITLE;

  our $Default_Resolution;
  our $tmp_stdin;
  our $tmpdir;
  our $Output_File_Name;

  # $prog   viewer program
  # $rl     resource list
  unlink $tmp_stdin unless $Debug{'KEEP'};
  $Output_File_Name = '';

  my @title = @REG_TITLE;
  @title = ($Opt{'TITLE'}) unless @title;
  @title = () unless @title;

  foreach my $n (@title) {
    next unless $n;
    $n =~ s/^,+// if $n =~ /^,/;
    next unless $n;
    $Output_File_Name = $Output_File_Name . ',' if $Output_File_Name;
    $Output_File_Name = "$Output_File_Name$n";
  }                # foreach (@title)

  $Output_File_Name =~ s/^,+//;
  $Output_File_Name = '-' unless $Output_File_Name;
  $Output_File_Name = File::Spec->catfile($tmpdir, $Output_File_Name);

### main_set_resources()
  unless ($Display{'PROG'}) {    # for example, for groff mode
    $Display{'ARGS'} = '';
    return 1;
  }

  my %h = &where_is_prog($Display{'PROG'});
  my $prog = $h{'file'};
  if ($Display{'ARGS'}) {
    $Display{'ARGS'} = "$h{'args'} $Display{'ARGS'}";
  } else {
    $Display{'ARGS'} = $h{'args'};
  }

  my @rl = ();

  if ($Opt{'BD'}) {
    if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
      push @rl, '-bd', $Opt{'BD'};
    }
  }

  if ($Opt{'BG'}) {
    if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
      push @rl, '-bg', $Opt{'BG'};
    } elsif ($prog eq 'kghostview') {
      push @rl, '--bg', $Opt{'BG'};
    } elsif ($prog eq 'xpdf') {
      push @rl, '-papercolor', $Opt{'BG'};
    }
  }

### main_set_resources()
  if ($Opt{'BW'}) {
    if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
      push @rl, '-bw', $Opt{'BW'};
    }
  }

  if ($Opt{'FG'}) {
    if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
      push @rl, '-fg', $Opt{'FG'};
    } elsif ($prog eq 'kghostview') {
      push @rl, '--fg', $Opt{'FG'};
    }
  }

  if ($Opt{'FN'}) {
    if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
      push @rl, '-fn', $Opt{'FN'};
    } elsif ($prog eq 'kghostview') {
      push @rl, '--fn', $Opt{'FN'};
    }
  }

  if ($Opt{'GEOMETRY'}) {
    if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
      push @rl, '-geometry', $Opt{'GEOMETRY'};
    } elsif ($prog eq 'kghostview') {
      push @rl, '--geometry', $Opt{'GEOMETRY'};
    }
  }

### main_set_resources()
  if ($Opt{'RESOLUTION'}) {
    if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
      push @rl, '-resolution', $Opt{'RESOLUTION'};
    } elsif ($prog eq 'xpdf') {
      if ($Display{'PROG'} !~ / -z/) { # if xpdf does not have option -z
    if ($Default_Resolution == 75) {
      push @rl, '-z', 104;
    } elsif ($Default_Resolution == 100) { # 72dpi is '100'
      push @rl, '-z', 139;
    }
      }
    }                # if $prog
  } else {            # empty $Opt{RESOLUTION}
    $Opt{'RESOLUTION'} = $Default_Resolution;
    if ($prog =~ /^(gxditview|xditview)$/) {
      push @rl, '-resolution', $Default_Resolution;
    } elsif ($prog eq 'xpdf') {
      if ($Display{'PROG'} !~ / -z/) { # if xpdf does not have option -z
    if ($Default_Resolution == 75) {
      push @rl, '-z', 104;
    } elsif ($Default_Resolution == 100) { # 72dpi is '100'
      push @rl, '-z', 139;
    }
      }
    }                # if $prog
  }                # if $Opt{RESOLUTION}

  if ($Opt{'ICONIC'}) {
    if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
      push @rl, '-iconic';
    }
  }

### main_set_resources()
  if ($Opt{'RV'}) {
    if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi)$/) {
      push @rl, '-rv';
    }
  }

  if (@{$Opt{'XRM'}}) {
    if ($prog =~ /^(ghostview|gv|gxditview|xditview|xdvi|xpdf)$/) {
      foreach (@{$Opt{'XRM'}}) {
    push @rl, '-xrm', $_;
      }
    }
  }

  if (@title) {
    if ($prog =~ /^(gxditview|xditview)$/) {
      push @rl, '-title', $Output_File_Name;
    }
  }

  my $args = join ' ', @rl;
  if ($Display{'ARGS'}) {
    $Display{'ARGS'} = "$args $Display{'ARGS'}";
  } else {
    $Display{'ARGS'} = $args;
  }

  1;
}                # main_set_resources()


########################################################################
# set resources
########################################################################

##########
# main_display ()
#
# Do the actual display of the whole thing.
#
# Globals:
#   in: $Display{MODE}, $Opt{DEVICE}, @Addopts_Groff,
#       $fh_cat, $tmp_cat, $Opt{PAGER}, $Output_File_Name
#
sub main_display {
  our ( %Display, %Opt, %Debug, %Viewer_tty, %Viewer_X );

  our @Addopts_Groff;

  our ( $groggy, $modefile, $addopts, $fh_cat, $tmp_cat, $tmpdir );
  our ( $Output_File_Name, $Default_tty_Device );

  $addopts = join ' ', @Addopts_Groff;

  if (-z $tmp_cat) {
    warn "groffer: empty input\n";
    &clean_up();
    return 1;
  }

  $modefile = $Output_File_Name;

  # go to the temporary directory to be able to access internal data files
  chdir $tmpdir;

### main_display()
 SWITCH: foreach ($Display{'MODE'}) {
    /^groff$/ and do {
      push @Addopts_Groff, "-T$Opt{'DEVICE'}" if $Opt{'DEVICE'};
      $addopts = join ' ', @Addopts_Groff;
      $groggy = `cat $tmp_cat | grog`;
      die "main_display(): grog error;" if $?;
      chomp $groggy;
      print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
      &_do_opt_V();
      unlink $modefile;
      rename $tmp_cat, $modefile;
      system("cat $modefile | $groggy $addopts");
      &clean_up();
      next SWITCH;
    };                # /groff/

    /^(text|tty)$/ and do {
      my $device;
      if (! $Opt{'DEVICE'}) {
    $device = $Opt{'TEXT_DEVICE'};
    $device = $Default_tty_Device unless $device;
      } elsif ($Opt{'DEVICE'} =~ /^(ascii||cp1047|latin1|utf8)$/) {
    $device = $Opt{'DEVICE'};
      } else {
    warn "main_display(): wrong device for $Display{'MODE'} mode: " .
      "$Opt{'DEVICE'}";
      }
      $groggy = `cat $tmp_cat | grog -T$device`;
      die "main_display(): grog error;" if $?;
      chomp $groggy;
      print STDERR "grog output: " . $groggy . "\n" if $Debug{'GROG'};
      if ($Display{'MODE'} eq 'text') {
    &_do_opt_V();
    system("cat $tmp_cat | $groggy $addopts");
    &clean_up();
    next SWITCH;
      }

### main_display()
      # mode is not 'text', but 'tty'
      my %pager;
      my @p;
      push @p, $Opt{'PAGER'} if $Opt{'PAGER'};
      push @p, $ENV{'PAGER'} if $ENV{'PAGER'};
      foreach (@p) {
    %pager = &where_is_prog($_);
    next unless %pager;
    if ($pager{'file'} eq 'less') {
      if ($pager{'args'}) {
        $pager{'args'} = "-r -R $pager{'args'}";
      } else {
        $pager{'args'} = '-r -R';
      }
    }
    last if $pager{'file'};
      }                # foreach @p
      unless (%pager) {
    foreach (@{$Viewer_tty{'TTY'}}, @{$Viewer_X{'TTY'}}, 'cat') {
      next unless $_;
      %pager = &where_is_prog($_);
      last if %pager;
    }
      }
      die "main_display(): no pager program found for tty mode;"
    unless %pager;
      &_do_opt_V();
      system("cat $tmp_cat | $groggy $addopts | " .
         "$pager{'fullname'} $pager{'args'}");
      &clean_up();
      next SWITCH;
    };                # /text|tty/

    /^source$/ and do {
      open $fh_cat, "<$tmp_cat";
      foreach (<$fh_cat>) {
    print "$_";
      }
      &clean_up();
      next SWITCH;
    };

### main_display()
    /^dvi$/ and do {
      if ($Opt{'DEVICE'} && $Opt{'DEVICE'} ne 'dvi') {
    warn "main_display(): " .
      "wrong device for $Display{'MODE'} mode: $Opt{'DEVICE'};"
      }
      $modefile .= '.dvi';
      $groggy = `cat $tmp_cat | grog -Tdvi`;
      die "main_display(): grog error;" if $?;
      chomp $groggy;
      print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
      &_do_display();
      next SWITCH;
    };

    /^html$/ and do {
      if ($Opt{'DEVICE'} && $Opt{'DEVICE'} ne 'html') {
    warn "main_display(): " .
      "wrong device for $Display{'MODE'} mode: $Opt{'DEVICE'};"
      }
      $modefile .= '.html';
      $groggy = `cat $tmp_cat | grog -Thtml`;
      die "main_display(): grog error;" if $?;
      chomp $groggy;
      print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
      &_do_display();
      next SWITCH;
    };

    /^xhtml$/ and do {
      if ($Opt{'DEVICE'} && $Opt{'DEVICE'} ne 'xhtml') {
    warn "main_display(): " .
      "wrong device for $Display{'MODE'} mode: $Opt{'DEVICE'};"
      }
      $modefile .= '.xhtml';
      $groggy = `cat $tmp_cat | grog -Txhtml`;
      die "main_display(): grog error;" if $?;
      chomp $groggy;
      print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
      &_do_display();
      next SWITCH;
    };


    /^pdf$/ and do {
      $modefile .= '.pdf';
      $groggy = `cat $tmp_cat | grog -Tpdf --ligatures`;
      die "main_display(): grog error;" if $?;
      chomp $groggy;
      print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
      &_do_display();
      next SWITCH;
    };


    /^pdf2$/ and do {
      if ($Opt{'DEVICE'} && $Opt{'DEVICE'} ne 'ps') {
    warn "main_display(): " .
      "wrong device for $Display{'MODE'} mode: $Opt{'DEVICE'};"
      }
      $modefile .= '.ps';
      $groggy = `cat $tmp_cat | grog -Tps`;
      die "main_display(): grog error;" if $?;
      chomp $groggy;
      print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
      &_do_display(\&_make_pdf2);
      next SWITCH;
    };

### main_display()
    /^ps$/ and do {
      if ($Opt{'DEVICE'} && $Opt{'DEVICE'} ne 'ps') {
    warn "main_display(): " .
      "wrong device for $Display{'MODE'} mode: $Opt{'DEVICE'};"
      }
      $modefile .= '.ps';
      $groggy = `cat $tmp_cat | grog -Tps`;
      die "main_display(): grog error;" if $?;
      chomp $groggy;
      print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
      &_do_display();
      next SWITCH;
    };

    /^x$/ and do {
      my $device;
      if ($Opt{'DEVICE'} && $Opt{'DEVICE'} =~ /^X/) {
    $device = $Opt{'DEVICE'};
      } else {
    if ($Opt{'RESOLUTION'} == 100) {
      if ( $Display{'PROG'} =~ /^(g|)xditview$/ ) {
        # add width of 800dpi for resolution of 100dpi to the args
        $Display{'ARGS'} .= ' -geometry 800';
        $Display{'ARGS'} =~ s/^ //;
      }
    } else {        # RESOLUTIOM != 100
      $device = 'X75-12';
    }            # if RESOLUTIOM
      }                # if DEVICE
      $groggy = `cat $tmp_cat | grog -T$device -Z`;
      die "main_display(): grog error;" if $?;
      chomp $groggy;
      print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
      &_do_display();
      next SWITCH;
    };

### main_display()
    /^X$/ and do {
      if (! $Opt{'DEVICE'}) {
    $groggy = `cat $tmp_cat | grog -X`;
    die "main_display(): grog error;" if $?;
    chomp $groggy;
    print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
      } elsif ($Opt{'DEVICE'} =~ /^(X.*|dvi|html|xhtml|lbp|lj4|ps)$/) {
    # these devices work with
    $groggy = `cat $tmp_cat | grog -T$Opt{'DEVICE'} -X`;
    die "main_display(): grog error;" if $?;
    chomp $groggy;
    print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
      } else {
    warn "main_display(): wrong device for " .
      "$Display{'MODE'} mode: $Opt{'DEVICE'};";
    $groggy = `cat $tmp_cat | grog -Z`;
    die "main_display(): grog error;" if $?;
    chomp $groggy;
    print STDERR "grog output: $groggy\n" if $Debug{'GROG'};
      }                # if DEVICE
      &_do_display();
      next SWITCH;
    };

    /^.*$/ and do {
      die "main_display(): unknown mode '$Display{'MODE'}';";
    };

  }                # SWITCH
  1;
} # main_display()


########################
# _do_display ([<prog>])
#
# Perform the generation of the output and view the result.  If an
# argument is given interpret it as a function name that is called in
# the midst (actually only for 'pdf').
#
sub _do_display {
  our ( %Display, %Debug, %Opt );

  our ( $modefile, $tmpdir, $tmp_cat, $addopts, $groggy );
  our ( $Viewer_Background );

  &_do_opt_V();
  unless ($Display{'PROG'}) {
    system("$groggy $addopts $tmp_cat");
    &clean_up();
    return 1;
  }
  unlink $modefile;
  die "_do_display(): empty output;" if -z $tmp_cat;
  system("cat $tmp_cat | $groggy $addopts >$modefile");
  die "_do_display(): empty output;" if -z $modefile;
  &print_times("before display");
  if ($_[0] && ref($_[0]) eq 'CODE') {
    $_[0]->();
  }
  unlink $tmp_cat unless $Debug{'KEEP'};

  if ( $Opt{'STDOUT'} ) {
    my $fh;
    open $fh, "<$modefile";
    foreach (<$fh>) {
      print;
    }
    close $fh;
    return 1;
  }

  if ( $Viewer_Background ) {
    if ($Debug{'KEEP'}) {
      exec "$Display{'PROG'} $Display{'ARGS'} $modefile &";
    } else {
      exec "{ $Display{'PROG'} $Display{'ARGS'} $modefile; " .
    "rm -rf $tmpdir; } &";
    }
  } else {
    system("$Display{'PROG'} $Display{'ARGS'} $modefile");
    &clean_up();
  }
} # _do_display() of main_display()


#############
# _do_opt_V ()
#
# Check on option '-V'; if set print the corresponding output and leave.
#
# Globals: @ARGV, $Display{MODE}, $Display{PROG},
#          $Display{ARGS}, $groggy,  $modefile, $addopts
#
sub _do_opt_V {
  our %Opt;
  our %Display;
  our @ARGV;

  our ($groggy, $modefile, $addopts);

  if ($Opt{'V'}) {
    $Opt{'V'} = 0;
    print "Parameters: @ARGV\n";
    print "Display Mode: $Display{'MODE'}\n";
    print "Output file: $modefile\n";
    print "Display prog: $Display{'PROG'} $Display{'ARGS'}\n";
    print "Output of grog: $groggy $addopts\n";
    my $res = `$groggy $addopts\n`;
    chomp $res;
    print "groff -V: $res\n";
    exit 0;
  }
  1;
} # _do_opt_V() of main_display()


##############
# _make_pdf2 ()
#
# Transform to ps/pdf format; for pdf2 mode in _do_display().
#
# Globals: $md_modefile (from main_display())
#
sub _make_pdf2 {
  our %Debug;
  our %Opt;

  our $PDF_Did_Not_Work;
  our $PDF_Has_gs;
  our $PDF_Has_ps2pdf;
  our $Dev_Null;
  our $modefile;

  die "_make_pdf2(): pdf2 mode did not work;" if $PDF_Did_Not_Work;
  my $psfile = $modefile;
  die "_make_pdf2(): empty output;" if -z $modefile;
  $modefile =~ s/\.ps$/.pdf/;
  unlink $modefile;
  my $done;
  if ($PDF_Has_ps2pdf) {
    system("ps2pdf $psfile $modefile 2>$Dev_Null");
    $done = ! $?;
  }
  if (! $done && $PDF_Has_gs) {
    system("gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite " .
       "-sOutputFile=$modefile -c save pop -f $psfile 2>$Dev_Null");
    $done = ! $?;
  }
  if (! $done) {
    $PDF_Did_Not_Work = 1;
    warn '_make_pdf2(): Could not transform into pdf format, ' .
      'the Postscript mode (ps) is used instead;';
    $Opt{'MODE'} = 'ps';
    &main_set_mode();
    &main_set_resources();
    &main_display();
    exit 0;
  }
  unlink $psfile unless $Debug{'KEEP'};
  1;
} # _make_pdf2() of main_display()


1;
########################################################################
### Emacs settings
# Local Variables:
# mode: CPerl
# End:

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0085 ]--