home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / perl / scripts-convex / boss < prev    next >
Encoding:
Text File  |  1993-07-14  |  3.6 KB  |  188 lines

  1. #!/usr/bin/perl 
  2. #
  3. # boss, peon - who works for whom
  4. #
  5. # tom christiansen, 25 Oct
  6. #
  7. # given a data file with (peon boss) pairs, 
  8. # fetch peons of a given boss, or boss of a
  9. # given peon boss.  recurse all the way with -r,
  10. # limit depth with -2, -3, etc.  
  11.  
  12.  
  13. $DATA = "/usr/spool/globdata/etc/reports_to";
  14.  
  15. sub usage {
  16.     print STDERR <<EOM;
  17. usage: $0 [-$opts] [user ...]
  18.     -#    recursion depth
  19.     -r     recurse all the way
  20.     -b    boss
  21.     -e    empl (also -p)
  22.     -a    list all
  23.     -s    sort
  24.     -v    verbose
  25.     -d    debug
  26.     -B    rebuild databases
  27.     -F db    alternate database
  28. EOM
  29.     exit 2;
  30.  
  31. MAIN: {
  32.  
  33.     do 'getopts.pl' || die "can't do getopts.pl: " . ($@? $@ : $!); 
  34.     $opts = 'vasbBepdr123456789F:';
  35.     &Getopts($opts) || &usage;
  36.  
  37.     if ($opt_r) {
  38.     $maxdepth = 100;
  39.     } else {
  40.     for $i (reverse 1..9) {
  41.         if (eval "defined \$opt_$i") {
  42.         $maxdepth = $i;
  43.         last;
  44.         } 
  45.     } 
  46.     }
  47.  
  48.     $sort = $opt_s;
  49.     $debug = $opt_d;
  50.     $verbose = $opt_v;
  51.     $listall = $opt_a;
  52.  
  53.     $want = 'boss' if $opt_b;
  54.     $want = 'peon' if $opt_p || $opt_e; 
  55.     $rebuild = $opt_B;
  56.  
  57.     if ($0 =~ m#/?boss[^/]*$#) {
  58.     $want = 'boss';
  59.     } elsif ($0 =~ m#/?(empl|peon)[^/]*$#) {
  60.     $want = 'peon';
  61.     } elsif (!$want) {
  62.     warn "$0: neither boss nor empl specified\n";
  63.     &usage;
  64.     } 
  65.  
  66.     if ($listall && @ARGV) {
  67.     warn "$0: explicit list conflict with request to list all\n";
  68.     &usage;
  69.     } 
  70.  
  71.     $DATA = $opt_F || $ENV{'peersfile'} || $DATA;
  72.  
  73.     &init;
  74.  
  75.     *which = eval "*$want";    # create alias
  76.  
  77.     if ($listall) {
  78.     @ARGV = sort grep (!/ /,keys %which);
  79.     $verbose = 1;
  80.     } 
  81.  
  82.     for $target (@ARGV) {
  83.      local(%duplicate);
  84.      if (!defined $boss{$target} && !defined $peon{$target}) {
  85.         warn "$0: $target unknown\n";
  86.         next;
  87.      } 
  88.      @list = &traverse($target);
  89.      @list = sort @list if $sort;
  90.      print "$target: " if $verbose;
  91.      print join(' ',@list) if @list;
  92.      print "\n" if $verbose || @list;
  93.     } 
  94.  
  95.     exit 0;
  96. }; # end main
  97.  
  98. sub traverse {
  99.     local(%seen, @who, $user, @newlist, @tmplist);
  100.  
  101.     $depth++;
  102.  
  103.     @who = @_;
  104.  
  105.     foreach $user (@who) {
  106.     next if $duplicate{$user}++;
  107.  
  108.     @tmplist = split(' ',$which{$user});
  109.     print "$depth $want of $user is <@tmplist>\n"
  110.         if $debug && @tmplist;
  111.  
  112.     push (@tmplist, &traverse(@tmplist)) if $maxdepth > $depth;
  113.     push(@newlist,@tmplist);
  114.     } 
  115.  
  116.     print "$depth returning $want of <@who> as <@newlist>\n" 
  117.     if $debug && @newlist && @who == 1;
  118.  
  119.     $depth--;
  120.  
  121.     return grep(!$seen{$_}++,@newlist);
  122.  
  123. sub rebuild {
  124.     warn "$0: rebuilding DB from $DATA\n";
  125.     &opendb('writing');
  126.     %boss = %peon = ();
  127.     open DATA || die "can't open $DATA: $!";
  128.     while (<DATA>) {
  129.     split;
  130.     next if $#_ > 1;
  131.     ($peon, $boss) = @_;
  132.     $peon{$boss} .= ' ' . $peon;
  133.     $boss{$peon} .= ' ' . $boss;
  134.     } 
  135.     &closedb;
  136. }
  137.  
  138. sub init {
  139.  
  140.     local($data_age, $base, $page);
  141.     
  142.     $data_age = &age($DATA);
  143.     $bage     = &age("$DATA.boss.pag");
  144.     $page     = &age("$DATA.peon.pag");
  145.  
  146.     if ($rebuild || ($bage < $data_age) || ($page < $data_age)) {
  147.     &rebuild;
  148.     }
  149.     &opendb('reading');
  150.  
  151. sub closedb {
  152.     dbmclose(boss) || die "$0: can't dbmclose boss: $!\n";
  153.     dbmclose(peon) || die "$0: can't dbmclose peon: $!\n";
  154.  
  155. sub opendb {
  156.     local($mode) = @_;
  157.  
  158.     do _opendb('boss');
  159.     do _opendb('peon');
  160.  
  161. sub _opendb {
  162.     local($what) = @_;
  163.     local($file) = $DATA . '.' . $what;
  164.  
  165.     if ($mode eq 'writing') {
  166.     for $ext ('pag', 'dir') {
  167.         open(FILE, ">$file.$ext") || die "can't write $file.$ext\n";
  168.         close FILE;
  169.     }
  170.     } 
  171.  
  172.     eval <<EO_EVAL;
  173.     dbmopen($what, "$file", \$mode eq 'writing' ? 0644 : 0444) 
  174.         || die "$0: can't dbmopen $file for \$mode: \$!\n";
  175. EO_EVAL
  176.     die $@ if $@;
  177.  
  178.  
  179. sub age { 
  180.     return (stat($_[0]))[9];
  181. }
  182.