#!/usr/bin/env perl # -*- perl -*- # pod - an aide to setting search paths using structured software areas # # Christopher Alexander North-Keys # 0.1 Sun Aug 29 03:59:36 CDT 1993 (begun) # 0.2 Mon Aug 30 09:15:07 CDT 1993 # 0.3 Mon Sep 20 03:54:56 CDT 1993 (added LD_LIBRARY_PATH) # 0.4 Mon Sep 20 10:09:04 CDT 1993 (rewrite) # 0.5 Wed Jun 14 04:39:33 CDT 1995 (another rewrite, in perl) # 0.6 Tue Apr 23 11:55:40 CDT 1996 (add catman support) # 0.7 Fri Aug 16 12:19:53 CDT 1996 (backwards compat with perl4) # 0.8 Wed Nov 19 11:56:23 CST 1997 (added strict, $format, multiple outputs) use strict; my $version = '0.9 Wed Nov 19 16:17:13 CST 1997'; my @pods = (); my $pod = '/pod'; # dir in which all pods are located my $env = 'PODS'; # envvar listing pod to prefix to default pods my $nis = 'auto.pod'; # default pods my $etc = '/etc/pods'; # default pods my $path_delim = ':'; # delimiter for paths upon output my $path_delim_frenzied = 0; # replace ':' with $path_delim in %e my $cull = 1; # whether to cull nonextant path components my $format = "%p%n"; my %PathVar; $PathVar{'bin'} = 'PATH'; $PathVar{'man'} = 'MANPATH'; $PathVar{'lib'} = 'LDPATH'; # should be copied to LD_LIBRARY_PATH as well $PathVar{'include'} = 'INCPATH'; sub Version { print("pod Copyright (c) 1993-1997 C. Alex. North-Keys " . ''. "\n" . "Version: $version\n"); print("Prehistory:\n" . "\tConceptualized in 1989 as a way of handling large software\n" . "\tcollections in a standard way that retained their package\n" . "\tidentity. At that time, most admins were simply putting\n" . "\teverything in /usr/local. First used with /vol at the Freie\n" . "\tUniversität Berlin (math.fu-berlin.de), then later on /pod\n" . "\tat Origin Systems (origin.ea.com). These prototypes showed\n" . "\tgreat potential when used in combination with the\n" . "\tautomounter, since packages were now accessed by package\n" . "\tname, and the underlying location of the data both hidden\n" . "\tand dynamically modifiable by the admin. Basically this\n" . "\tmeans admins may move packages around the net w/o warning.\n" ); print("Notes:\n" . "\tThis version is designed to allow sufficient output control\n" . "\tso as to generate all the needed eval(1)-able output for any\n" . "\tshell with only one call to pod(1).\n" ); } sub Help { print("Syntax:\n" . " pod [ -h | -v | -p ]\n" . " pod [-s ] [-k] [-[d|D] ] -[b|i|l|m] [--] " . "[]" . "\n" . "\t-h help, output this help (the default) and exit\n" . "\t-v version, output version information/commentary and exit\n" . "\t-p pods, output the current pod list and exit\n" . "\n" . "\t-s set pod list to (delimited by \":\" or \" \")\n" . "\t-k keep nonextant path elements, which normally are culled\n" . "\n" . "\t-d delim, set the path delimiter to be (not \"@\")\n" . "\t-D like -d, but also replaces \":\" in %e (for *csh users)\n" . "\t-f format, set format string for path outputs. Escapes:\n" . "\n" . "\t-b bins, output the pod command (bin) search path\n" . "\t-i incs, output the pod include search path\n" . "\t-l libs, output the pod library search path\n" . "\t-m mans, output the pod manual search path\n" . "\t %p - full path\n" . "\t %t - path type (ie: 'bin', 'man', 'lib', 'inc')\n" . "\t %v - path variable (ie: PATH, MANPATH, LDPATH, INCPATH)\n" . "\t %e - pre-existing environment value of corresponding %v\n" . "\t %n - newline\n" . "\t-- no more options (anything following is )\n" . "\tWith , runs a cmd with PATH, MANPATH, LDPATH, INCPATH,\n" . "\t LD_LIBRARY_PATH, and INCPATH variables, modified to\n" . "\t include elements as would be seen by -b, -l, and -m.\n" . "\tMultiple path requests are output one per line,\n" . "\t each formatted as directed by -f (default \"%p\\n\"\n" . "\tpod catenates available pods (unless overriden by -s) from:\n" . "\t the PODS environment variable, if it exists\n" . "\t the ", $etc, " file (or output of, if executable)\n" . "\t the ", $nis, " NIS map\n" . "\n" . "Example for sh family:\n" . "\t" . 'eval `pod \\' . "\n" . "\t\t" . '-f "%v=$HOME/bin:%e:/usr/games:%p\n" -b \\' . "\n" . "\t\t" . '-f "%v=/usr/man:/usr/local/man:%p\n" -m \\' . "\n" . "\t\t" . '-f "%v=/usr/lib:/usr/local/lib:%p\n" -l \\' . "\n" . "\t\t" . '-f "%v=/usr/include:/usr/local/include:%p\n" -i`' . "\n" . "\t" . 'LD_LIBARY_PATH=$LDPATH # compatibility' . "\n" . "\texport PATH MANPATH LDPATH LD_LIBRARY_PATH INCPATH\n" ); return 0; } sub SetPods { return if(0 + @pods); my (@nis_pods, @etc_pods, @env_pods); @env_pods = split(/:/, $ENV{$env}); if(open(ETC, (-x $etc ? "$etc |" : $etc))) { my $line; while($line = ) { push(@etc_pods, split(' ', $line)); } close(ETC); chomp(@etc_pods); } if(open(NIS, 'ypcat -k ' . $nis . ' 2>/dev/null |' )) { @nis_pods = ; close(NIS); chomp(@nis_pods); @nis_pods = grep(s/^(\w*)\W.*$/\1/, @nis_pods); @nis_pods = sort(@nis_pods); } @pods = (@env_pods, @etc_pods, @nis_pods); } sub Path # arg:subdir ret:0 out:pathtext { my(@subs) = @_; # sought subdirectories &SetPods(); my($dirs, $pod, $sub, $dir); for $pod (@pods) { for $sub (@subs) { my $dir = "/pod/" . $pod . "/" . $sub; if( (!$cull) || -d $dir ) { $dirs = $dirs . $path_delim if ($dirs); $dirs = $dirs . $dir; } } } return $dirs; } sub PathSetAll { $ENV{'PATH'} = join($path_delim, (&Path('bin'), $ENV{'PATH'})); $ENV{'MANPATH'} = join($path_delim, (&Path('man'), $ENV{'MANPATH'})); $ENV{'LDPATH'} = $ENV{'LD_LIBRARY_PATH'} = join($path_delim, (&Path('lib'), $ENV{'LD_LIBRARY_PATH'})); $ENV{'INCPATH'} = join($path_delim, (&Path('include'), $ENV{'INCPATH'})); } sub PathOutput # 'bin'|'lib'|'include'|'man' { my (@types) = @_; if(@types[0] eq 'man') { my (@mandirs) = 'man'; splice(@mandirs, @mandirs, @mandirs, 'catman') if(-d '/usr/catman' || -d '/usr/share/catman'); @types = @mandirs; } my $output = $format; my $p_replacement = &Path(@types); my $t_replacement = $types[0]; my $v_replacement = $PathVar{$t_replacement}; my $e_replacement = $ENV{$v_replacement}; $e_replacement =~ s/:/$path_delim/g if($path_delim_frenzied); #csh $output =~ s/%p/$p_replacement/g; $output =~ s/%t/$t_replacement/g; $output =~ s/%v/$v_replacement/g; $output =~ s/%e/$e_replacement/g; $output =~ s/%n/\n/g; print($output); } sub main { my(@argv) = @_; my($i); my($sought); # what sought: bin lib man, (etc)? if (0 == @argv) { return ! &Help; } # should use stderr for($i = 0 ; $argv[$i] =~ /^-/ ; ++$i) { my ($x) = $argv[$i]; if ($x =~ /^-h/) { return &Help; } elsif ($x =~ /^-v/) { return &Version; } elsif ($x =~ /^-k/) { $cull = 0; } elsif ($x =~ /^-s/) { @pods = split('[: ]', $argv[++$i]); } elsif ($x =~ /^-d/) { $path_delim = $argv[++$i]; $path_delim_frenzied = 0;} elsif ($x =~ /^-D/) { $path_delim = $argv[++$i]; $path_delim_frenzied = 1;} elsif ($x =~ /^-p/) { &SetPods; return print(join(' ', @pods), "\n"); } elsif ($x =~ /^-b/) { &PathOutput('bin'); } elsif ($x =~ /^-l/) { &PathOutput('lib'); } elsif ($x =~ /^-i/) { &PathOutput('include'); } elsif ($x =~ /^-m/) { &PathOutput('man'); } elsif ($x =~ /^-f/) { $format = $argv[++$i]; } elsif ($x =~ /^--/) { ++$i; last; } else { return ! &Help; } # oops } if($i < @argv) { &PathSetAll; splice(@argv, 0, $i); print(join(' ', @argv) . "\n"); exec(@argv); print("pod - exec: requested execution could not be accomplished.\n"); } } &main(@ARGV); # Local Variables: # # tab-width: 4 # # End: # #-----------------------------eof