# -*-perl-*-
#
#   Copyright (c) 1996 Network Appliance, Inc.
#   Copyright (c) 2002 PiroNet NDH AG
#
#   You may distribute under the terms of the Artistic License, as
#   specified in the README file included in the cvslines
#   distribution.
#
#   Original Author: Richard Geiger for Network Appliance, Inc.
#   Adaption to cvs >=1.11 by Juergen Jatzkowski and Ingo Rockel
#
#  $Id: cvslines-status,v 1.4 2002/06/07 13:33:42 irockel Exp $
#

#  This file is used by "cvslines".
#  It is not intended for standalone execution.

$Logfrom = "status";

#  functions unique to $Mynamebase status
#

sub rcsrevs_file
{
  my ($file) = @_;
  my $dir;
  my $dummy;
  my $filename;
  my $dummy;
  my ($Ent_name, $Ent_rev, $Ent_time, $Ent_opts, $Ent_tag);
  my $this_line;
  my $this_lgroup;
  my $linename;
  my $spec;
  my $state;
  my $specrev;

  $dir = &dirname($file);
  $file =~ s%^.*/%%;

  if ($dir ne $rcsrevs_file_lastdir)
    { if (! &module_config($dir, 1)) { $rcsrevs_file_lastdir = ""; next; } }

  @Entry = grep(/^\/$file\//, @CVS_Entries);

  if ($#Entry == -1)            
    {        
      if (! $rcsrevs_file_first) { print "\n"; } else { $rcsrevs_file_first = 0; }
      print "nothing known about $dir/$file\n";
      return;
    }

  if ($#Entry != 0)
    {
      print STDERR "$Myname: internal error: found more than one entry for \"$file\".\n";
      return;
    }

  ($dummy, $Ent_name, $Ent_rev, $Ent_time, $Ent_opts, $Ent_tag) = split(/\//, $Entry[0]);

  if ($Ent_rev eq "0" && $Ent_time !~ /^... ... .. ..:..:.. ....$/)
    {
      if (! $rcsrevs_file_first) { print "\n"; } else { $rcsrevs_file_first = 0; }
      print "$dir/$file: added but not yet committed.\n";
      return;
    }

  if (! &set_RCS_revs($CVS_Repository, "$dir/$file")) { next; }

  if (! $rcsrevs_file_first) { print "\n"; } else { $rcsrevs_file_first = 0; }
  print "$dir/$file\n";

  printf "   $Fmt\n", "line", "spec", " ", "spec rev", "cur rev";
  printf "   $Fmt\n", $D_Line, $D_Spec, " ", $D_Specrev, $D_Currev;

  set_Ent($file);

  $this_line = "?";

#print "Ent_tag <$Ent_Tag> CVS_Tag <$CVS_Tag>\n";

  foreach $line_name (@CVS_Lines)
    {


      ($spec, $state, $specrev) = &setspecs($line_name);
      if ($spec ne $Ent_Tag) { next; }

      #  If > 1 lines match, we need resolution...
      #
      if ($this_line ne "?") { $this_line = &this_line_resolve(); last; }
      $this_line = $line_name;
    }
  if ($this_line eq "?")
    { &noteNbail("problem: couldn't determine this_line for \"$file\"."); }

  $this_lgroup = $CVS_Lines_Lgroups{$this_line};

  foreach $CVS_line (@CVS_Lines)
    {
      my ($linename, $spec, $state) =
        ($CVS_line, $CVS_Lines_Spec{$CVS_line}, $CVS_Lines_State{$CVS_line});

      if ((! $Nolgroups) &&
        ($CVS_Lines_Lgroups{$CVS_line} ne $this_lgroup && ! $Showall)) { next; }

      if (defined($RCS_Tags{$spec}))
        { $specrev = $RCS_Tags{$spec}; }
      elsif ($spec eq "head")
        { $specrev = "head"; }
      else
        { $specrev = "none"; }

#print "CVS_Lines_Spec{$CVS_line} <$CVS_Lines_Spec{$CVS_line}> Ent_Tag <$Ent_Tag>\n";
      if ($CVS_Lines_Spec{$CVS_line} eq $Ent_Tag)
        { $tag = ">> "; }
      else
        {
          if ((! $Nolgroups) && $CVS_Lines_Lgroups{$CVS_line} ne $this_lgroup)
            { $tag = "xx "; } else { $tag = "   "; }
        }

      print $tag; printf "$Fmt\n", $linename, $spec, " ", $specrev, &rev_on_line($spec);
    }
        
  $rcsrevs_file_lastdir = $dir;
}


sub traverse
{
  my ($dir, $lev) = @_;
  
  my $dirent;
  my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
       $atime,$mtime,$ctime,$blksize,$blocks);

  my $dirhandle = "dh$lev";

  if (-d "$dir/CVS") { &rcsrevs_dir($dir); }

  if ($Norecurse) { return; }

  opendir($dirhandle, $dir);

  while (($dirent = readdir($dirhandle)))
    {
      if ($dirent eq "." || $dirent eq "..") { next; }
      if (-d $dirent && $dirent eq "CVS") { next; }
      ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
       $atime,$mtime,$ctime,$blksize,$blocks) = lstat("$dir/$dirent");
      if (-d _) { do traverse("$dir/$dirent", $lev+1); }
    }
  closedir($dirhandle);
}


sub rcsrevs_dir
{
  my ($dir) = @_;

  if (! open(F, "<$dir/CVS/Entries"))
    { print STDERR "$Myname: can't open \"$dir/CVS/Entries\": $!"; return 0; }

  while (<F>)
    {
      chop; ($type, $filename, $rev) = split(/\//, $_);
      if ($type eq "D") { next; }
      &rcsrevs_file("$dir/$filename");
    }
  close F;

}

$here = `/bin/pwd`; chop $here;
&log($here." ".join(" ", @Paths));

$rcsrevs_file_lastdir = "";
$rcsrevs_file_first = 1;


foreach $path (@Paths)
  {
    if (-d $path)
      { &traverse($path, 1); }
    else
      { &rcsrevs_file($path); }
  }

exit 0;

