home *** CD-ROM | disk | FTP | other *** search
- #!/u3/thesis/clipper/bin/perl # -*-perl-*-
- # Copyright (C) Khun Yee Fung clipper@csd.uwo.ca 1991
- # You can do anything to this program except selling it for profit or
- # pretending you wrote it. The copyright notice must be preserved in all
- # copies.
- # $Id: archie,v 1.2 1991/07/12 06:04:31 clipper Exp clipper $
- eval "exec perl -S $0 $*"
- if $running_under_some_shell;
-
- require 'archie.depend';
- require $socket;
- require 'resolver.pl';
- require 'newgetopt.pl';
- &NGetOpt('match=i', 'reg', 'exact', 'nocase', 'case', 'host=s',
- 'ffile=s', 'format=s', 'along');
- @prog = split('/', $0);
- $prog = $prog[$#prog];
- $usage =
- "Usage: $prog [-case, -exact, -reg, -nocase, -match count, -host host] word
- -case Case sensitive
- -nocase Case insensitive
- -exact Exact match
- -reg Regular expression match
- -match \# Max hits
- -host Instead of quiche.cs.mcgill.ca
- -ffile Use a format file
- -format Specify a format string
- -along Print output along the way, instead of all as once at the end
- ";
- if ($#ARGV < 0 || $#ARGV > 0) {
- die $usage;
- }
- @month = ('', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',
- 'Sep', 'Oct', 'Nov', 'Dec');
- $string = $ARGV[0];
- $port = 1525;
- $sockaddr = 'nna4C8';
- $hostname = '132.206.2.3';
- ($dum, $dum, $dum, $dum, $thisaddr) = gethostbyname($thishost);
- $match = 100; $case = 'S'; $along = 0;
- ($user) = getpwuid($<);
- $ffile = 0;
- $format = 'Host $host
-
- Location: $dir
- $type $modes $size $date $name
-
- ';
- if ($opt_along) {
- $along = 1;
- }
- if ($opt_match) {
- $match = $opt_match;
- }
- if ($opt_ffile) {
- $ffile = 1;
- if (!open(FFILE, "$opt_ffile")) {
- die "Can't open format file $opt_ffile\n";
- }
- $format = '';
- while ($_ = <FFILE>) {
- $format .= $_;
- }
- close(FFILE);
- }
- if ($opt_format) {
- if ($opt_ffile) {
- print "Format string ignored: a format file was specified\n";
- }
- $ffile = 0;
- $format = $opt_format;
- }
- if ($opt_case) {
- $case = 'C';
- }
- if ($opt_nocase) {
- $case = 'S';
- }
- if ($opt_host) {
- $hostname = $opt_host;
- }
- if ($opt_reg) {
- $case = 'R';
- }
- if ($opt_exact) {
- $case = '=';
- }
- if ($hostname =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/) {
- $thataddr = pack("CCCC", $1, $2, $3, $4);
- }
- elsif (!(($name, $aliases, $type, $len, $thataddr) =
- gethostbyname($hostname))) {
- $thataddr = &resolver($hostname, $server) || die "No such host";
- }
-
- $them = pack($sockaddr, &AF_INET, $port, $thataddr);
- $us = pack("n2C12", &AF_INET, 0, 0, 0, 0, 0);
- socket(DATA, &AF_INET, &SOCK_DGRAM, 0) || die "socket:$!\n";
- bind(DATA, $us) || die "bind: $!\n";
- select(STDOUT); $| = 1;
- $hosts = &list($them, $us, "VERSION 1\n",
- "AUTHENTICATOR UNAUTHENTICATED $user\n",
- "DIRECTORY ASCII ARCHIE/MATCH($match,0,$case)/$string\n",
- "LIST ATTRIBUTES COMPONENTS \n");
- if (!$along) {
- &output($hosts);
- }
- close(DATA);
-
- sub list {
- local($them, $us, @lines) = @_;
- local($answer, $ans, $timeout, $retries, $lines);
- local($nd_pkts, $no_pkts, $seq, $rin, $timeleft, $rout, $nfound);
- local($hdr_len, $id, $dum, $backoff, $ctlptr, $pkt_cid);
- local($packet) = 0;
-
- $timeout = 4;
- $retries = 3;
- $lines = join('', @lines);
- retry:
- send(DATA, $lines, 0, $them);
- $nd_pkts = 0;
- while (1) {
- $seq = 0;
- $rin = '';
- vec($rin, fileno(DATA), 1) = 1;
- ($nfound, $timeleft) = select($rout = $rin, '', '', $timeout);
- if ($timeleft == 0 && ($retries-- > 0)) {
- $timeout *= 2;
- goto retry;
- }
- $ans = '';
- if (!(recv(DATA, $ans, 10000, 0))) {
- die "recv: Can't recv. Die.\n";
- }
- $packet++;
- if (($hdr_len = ord(substr($ans, 0, 1))) < 20) {
- $seq = 0;
- ($hdr_len, $id, $seq, $nd_pkts, $dum, $backoff) =
- unpack("Cn*", $ans);
- if ($hdr_len < 5) {
- $seq = $nd_pkts = 1;
- }
- if ($hdr_len >= 11 && $backoff != 0) {
- $timeout = $backoff;
- }
- next if ($seq == 0);
- substr($ans, 0, $hdr_len) = '';
- }
- else {
- $id = 0;
- if (length($ans) - 20 > 0) {
- $ctlptr = length($ans) - 20;
- }
- else {
- $ctlptr = 0;
- }
- while (ord(substr($ans, $ctlptr, 1)) > 0) {
- $ctlptr++;
- }
- $ctlptr++;
- if ($ctlptr < length($ans) - 4) {
- $dum = unpack("n", substr($ans, $ctlptr, 2));
- if ($dum) {
- $pkt_cid = $dum;
- }
- $ctlptr += 2;
- if ($ctlptr < (length($ans))) {
- $seq = unpack("n", substr($ans, $ctlptr, 2));
- $ctlptr += 2;
- }
- if ($ctlptr < length($ans)) {
- $dum = unpack("n", substr($ans, $ctlptr, 2));
- if ($dum) {
- $nd_pkts = $dum;
- }
- $ctlptr += 2;
- }
- if ($ctlptr < length($ans)) {
- $ctlptr += 2;
- }
- if ($ctlptr < length($ans)) {
- $backoff = unpack("n", substr($ans, $ctlptr, 2));
- if ($backoff) {
- $timeout = $backoff;
- }
- $ctlptr += 2;
- }
- next if ($seq == 0);
- last;
- }
- else {
- if ($ans =~ /.*MULTI-PACKET\s*(\d+)\s+OF\s+(\d+)/) {
- $seq = $1;
- $nd_pkts = $2;
- }
- else {
- if ($along) {
- &output($ans);
- }
- return($ans);
- }
- }
- }
- $no_pkts++;
- $retries = 3;
- if ($along) {
- &output($ans);
- }
- $answer .= $ans;
- if ($nd_pkts == 0 || $no_pkts < $nd_pkts) {
- next;
- }
- last;
- }
- return($answer);
- }
-
- sub output {
- local($list) = @_;
- local(@lines, $dum, $arcmod, $lastmod, $modes, $host, $size, $dir);
- local($name);
-
- @lines = split(/\n/, $list);
- $host = '';
- while ($line = shift(@lines)) {
- if ($line =~ /LINK L/) {
- if ($host ne '') {
- &write($host, $isdir, $dir, $size, $arcmod, $modes,
- $lastmod, $name);
- }
- ($dum, $dum, $isdir, $name, $dum, $host, $dum, $dir, $dum, $dum) =
- split(/ /, $line);
- }
- elsif ($line =~ /LINK-INFO/) {
- ($dum, $dum, $attr, $dum, @info) = split(/ /, $line);
- if ($attr eq 'SIZE') {
- $size = join(' ', @info);
- }
- elsif ($attr eq 'UNIX-MODES') {
- $modes = join(' ', @info);
- }
- elsif ($attr eq 'ARC-MODTIME') {
- $arcmod = join(' ', @info);
- }
- elsif ($attr eq 'LAST-MODIFIED') {
- $lastmod = join(' ', @info);
- }
- }
- }
- if ($host ne '') {
- &write($host, $isdir, $dir, $size, $arcmod, $modes, $lastmod, $name);
- }
- }
-
- sub write {
- local($host, $isdir, $dir, $size, $arcmod, $modes, $lastmod, $name) = @_;
-
- $size = sprintf("%10d", $size);
- if ($isdir eq 'DIRECTORY') {
- $type = 'Directory';
- }
- else {
- $type = ' File';
- }
- $date = &date($lastmod);
- @path = split('/', $dir);
- pop(@path);
- $path = join('/', @path);
- $for = $format;
- $for =~ s/\$host/$host/g;
- $for =~ s/\$date/$date/g;
- $for =~ s/\$type/$type/g;
- $for =~ s/\$modes/$modes/g;
- $for =~ s/\$name/$name/g;
- $for =~ s/\$size/$size/g;
- $for =~ s/\$dir/$path/g;
- print $for;
- }
-
- sub date {
- local($date) = @_;
-
- $year = substr($date, 0, 4);
- $month = substr($date, 4, 2);
- $day = substr($date, 6, 2);
- $min = substr($date, 8, 2);
- $sec = substr($date, 10, 2);
- return "$year $month[$month] $day $min:$sec GMT";
- }
-
-