#!/bin/sh -- # A comment mentioning perl, indented for bash's sake. eval 'exec perl -S $0 ${1+"$@"}' if 0; ############################################################################### # for a default machine, should work on linux. needs netscape and wget. $View_Prg = "netscape -remote 'openURL(%URL,new-window)'"; # external view program. $Url_Fetch = "wget -O - -nv '%URL'"; # url fetcher $Url_Head_Fetch = "wget -O - -S --spider '%URL'"; # correct? need 2>&1 ? $X_Selection = "selection.tcl"; ############################################################################### # runge specials (comment out if you don't have these programs): $View_Prg = "av -w '%URL'"; # external view program. $Url_Fetch = "wcat -c '%URL'"; # url fetcher $Url_Head_Fetch = "wcat -h '%URL'"; # url header fetcher #$QT_View = "qtime '%URL'"; # quicktime url $QT_View = "xine --no-splash '%URL'"; # quicktime url ############################################################################### # edit these to match what you want to try, e.g. $Embed_Match = '(embed|bgsound)'; # ANY MORE? @Tags = ('src', 'song'); # ANY MORE? $Tagstr = join("= \n\t\t", @Tags, ''); ############################################################################### ############################################################################### # not much to tweak below here... $Force_Html = 0; $List_Only = 0; $Debug = 0; $Fake_Url = ''; $Selection = 0; $Loop = 0; $Warp = 0; chop($Program = `basename $0`); $Usage = <<"END"; plugin version 0.1 Copyright (c) 1999-2000 by Karl J. Runge $Program: Extract "$Embed_Match" plugin references from urls and play them with an external viewer(s). Usage: $Program Options: -h, -help This help. -l Only list the embedded urls, do not view them. -u Use as the base URL location when extracting "embed" from local html files. -H Force url interpretation to be HTML for even when url does not end in ".html" or ".htm" -d Debugging output (twice for even more) -s Use X selection -loop loop with prompting -warp try to warp the mouse to our window. Notes: Be sure to protect ? and & characters from the shell. The occurence of ? or & in the url implies -H (i.e. cgi script) If no url is given, you are prompted to paste in one. If the url is not HTML e.g. ".gif" then the command "$View_Prg" is used to view directly the url w/o any plugin interpretation. Embed is triggered by matching: <$Embed_Match ... = ... > These embed tags are recognized: $Tagstr END ############################################################################### # process cmd line args: LOOP: while (@ARGV) { $_ = shift; CASE: { /^-d$/ && ($Debug++, last CASE); /^-H$/ && ($Force_Html = 1, last CASE); /^-l$/ && ($List_Only = 1, last CASE); /^-u$/ && ($Fake_Url = shift, last CASE); /^-s$/ && ($Selection = 1, last CASE); /^-loop$/ && ($Loop = 1, last CASE); /^-warp$/ && ($Warp = 1, last CASE); /^--$/ && (last LOOP); # -- means end of switches /^-(-.*)$/ && (unshift(@ARGV, $1), last CASE); /^(-h|-help)$/ && ((print STDERR $Usage), exit 0, last CASE); if ( /^-(..+)$/ ) { # split bundled switches: local($y, $x) = ($1, ''); foreach $x (reverse(split(//, $y))) { unshift(@ARGV,"-$x") }; last CASE; } /^-/ && ((print STDERR "Invalid arg: $_\n$Usage"), exit 1, last CASE); unshift(@ARGV,$_); last LOOP; } } ############################################################################### if ( $Selection ) { $Tmp_File = "/tmp/$Program.$$.html"; system("selection.tcl > $Tmp_File"); unshift(@ARGV, $Tmp_File); } if ( $Warp ) { system("xwit -warp 20 20 1>/dev/null 2>&1"); } if ( ! @ARGV ) { # no url's supplied, so prompt user for one: print STDERR "Paste in the url (or blank to use the X-selection).\n"; print STDERR "URL: "; chop($x = ); if ( $x =~ /^\s*$/ && $ENV{DISPLAY} ) { print STDERR "trying X selection/clipboard...\n"; $x = `$X_Selection`; $x = &trim($x); } push(@ARGV, $x); } @url_list = @ARGV; # process each url: foreach $url (@url_list) { $url =~ s/^about://; $is_local = 0; $is_html = 0; $file = ''; $url0 = $url; # see if it happens to be a local file: if ( -f $url ) { $is_local = 1; $url0 = $Fake_Url; } # extract hostname and filename: if ( $url0 =~ m,^http://, ) { ($host, $file) = split(/\//, $', 2); } else { ($host, $file) = split(/\//, $url0, 2); } if ( ! $is_local && $file =~ /^\s*$/ ) { # blank $file # put in trailing "/" for toplevel sites: http://foo.com $url .= "/"; } # put a leading "/" separator onto $file (needed below in dirname()) $file = "/$file" unless $file =~ m,^/,; if ( $Debug > 0 ) { foreach $v (qw(is_local host file url0 url)) { eval "\$val = \$$v"; print STDERR "DBG: $v $val\n"; } } # open up a handle "HTML" giving us the html source: $cmd = ''; if ( $is_local ) { # local file: open(HTML, "<$url") || die "$!"; $is_html = 1; } elsif ( $Force_Html || $url =~ m,(\.htm[l]*|\.cgi|/)$,i ) { # HTML (note trailing / matches): $cmd = $Url_Fetch; $cmd =~ s/%URL/$url/g; open(HTML, "$cmd |"); $is_html = 1; } elsif ( $file =~ m,[\&\?], ) { # probably a CGI query: $cmd = $Url_Fetch; $cmd =~ s/%URL/$url/g; open(HTML, "$cmd |"); $is_html = 1; } else { # seems the thing is an arbitrary url, # we will not parse it... # but we will check the result of HEAD command on it $head_cmd = $Url_Head_Fetch; $head_cmd =~ s/%URL/$url/g; $head = `$head_cmd 2>&1`; print STDERR "DBG: HEAD $head_cmd:\n${head}DBG: ENDHEAD\n" if $Debug; if ( $head =~ /Content-Type:\s+.*html/i ) { $is_html = 1; if ( $head =~ m,Location:.*/[\r\n]+, ) { # HACK for directories... $file .= '/' unless $file =~ m,/$,; $url .= '/' unless $url =~ m,/$,; print STDERR "DBG: Set file to: $file\n" if $Debug; print STDERR "DBG: Set url to: $url\n" if $Debug; } $cmd = $Url_Fetch; $cmd =~ s/%URL/$url/g; open(HTML, "$cmd |"); } elsif ( $url =~ m,\.mov$, ) { # probably a quicktime movie $cmd = $QT_View; $cmd =~ s/%URL/$url/g; system("$cmd"); next; } else { $cmd = $View_Prg; $cmd =~ s/%URL/$url/g; $cmd =~ s/av/av -m/ if $url =~ /\.rpm/; print STDERR "NON_HTML: $cmd\n"; system("$cmd"); next; } } if ( $Debug > 0 ) { foreach $v (qw(is_html cmd)) { eval "\$val = \$$v"; print STDERR "DBG: $v $val\n"; } } # Glue all the html lines together into one string (with no newlines): $html = ''; $html_full = ''; while() { $html_full .= $_; chop; $html .= $_ . " "; } close(HTML); $html0 = $html; # save html for use with each tag we will try. if ( $Debug > 1 ) { print STDERR "HTML: ", '=' x 72, "\n"; print STDERR $html_full; print STDERR "HTML: ", '=' x 72, "\n"; } # Try each tag type: foreach $tag (@Tags) { print STDERR ">>> trying tag: ${tag}=\n" unless $List_Only; $html = $html0; # Now loop extracting occurences: # while ($html =~ /<\s*${Embed_Match}[^>]*${tag}\s*=\s*(\S+)[^>]*>/i ) { # new: while ($html =~ /<\s*${Embed_Match}[^>]*?${tag}\s*=\s*([^>]+?)>/i ) { $emb = $1; $src = $2; # $embed_match as 1 set of ()'s $emb_all = $&; $html = $'; # new: $src = trim($src); $src =~ s/\s.*$//; $ENV{PLUGIN_WIDTH} = ''; $ENV{PLUGIN_HEIGHT} = ''; if ( $emb_all =~ /\bWIDTH="?(\d+)/ ) { $ENV{PLUGIN_WIDTH} = $1; } if ( $emb_all =~ /\bHEIGHT="?(\d+)/ ) { $ENV{PLUGIN_HEIGHT} = $1; } $src0 = $src; print STDERR "SRC FOUND($emb): $src\n\t$emb_all\n"; if ( $Saw{$src}++ ) { next if $List_Only; print STDERR "REPEATED-1($emb): $src\n"; next } # clean up quotes, etc, around the src a bit: $src =~ s/[\\"']//g; $src =~ s,^\./+,,; # hack for "./" reference. if ( $src ne $src0 && $Saw{$src}++ ) { next if $List_Only; print STDERR "REPEATED-2($emb): $src\n"; next } if ( $src =~ m,^/, ) { $get = "http://${host}$src"; } elsif ( $src =~ m,^http:/, ) { $get = $src; } else { if ( $file =~ m,/$, ) { $dir = $file; } elsif ( $is_html || $Force_Html || $file =~ /(\.htm[l]*)$/i ) { $dir = &dirname($file); } else { # I don't think this is ever reached: $dir = $file; } $dir = "/$dir" unless $dir =~ m,^/,; $dir =~ s,/+$,,; $dir = '' if $dir eq "/"; if ( $dir =~ /^http:/ ) { $get = "$dir/$src"; } elsif ( $host =~ /^http:/ ) { $get = "${host}$dir/$src"; } else { $get = "http://${host}$dir/$src"; } } if ( $Saw{$get}++ ) { if ( $get ne $src ) { next if $List_Only; print STDERR "REPEATED-3($emb): $get\n"; next } } if ( $List_Only ) { print STDOUT "$get\n"; next; } print STDERR "*** EMBED($emb): SRC=$src DIR=$dir\n"; $cmd = $View_Prg; $cmd = $QT_View if $get =~ /\.mov$/; $cmd =~ s/%URL/$get/g; $cmd =~ s/av/av -m/ if $get =~ /\.rpm/; if ( ! $Play_Cmds{$cmd} ) { $Play_Cmds{$cmd} = 1; push (@Play_Cmds, $cmd); } print STDERR "*** EMBED($emb): CMD=$cmd\n"; # view it: system("$cmd"); } } } sub quit { exit 0; } unlink $Tmp_File if $Tmp_File; print STDERR "\n$Program: done.\n"; if ( $Loop ) { print 'Hit Enter to Finish, "m" for more, "l" to loop: '; $x = ; $x = trim($x); if ( $x =~ /^m$/i ) { exec "$Program -loop"; exit 1; } elsif ( $x =~ /^l$/i ) { $SIG{'INT'} = 'quit'; $SIG{'TERM'} = 'quit'; if ( @Play_Cmds ) { while (1) { foreach $cmd (@Play_Cmds) { $t0 = time; $cmd2 = $cmd; $cmd2 =~ s/^av /av -loop /; print STDERR "$cmd2\n"; system("$cmd2"); $t1 = time; if ( $t1 - $t0 < 3 ) { sleep 1; } else { &fsleep(0.1); } } } } else { $msg = $Program . " " . join(' ', @url_list); while (1) { $t0 = time; print STDERR "$msg\n"; system $Program, @url_list; $t1 = time; if ( $t1 - $t0 < 3 ) { sleep 1; } else { &fsleep(0.1); } } } } elsif ( $x ne '' ) { $x =~ s/'/%27/g; system("$Program '$x'"); } } exit 0; ############################################################################ # misc utils: sub trim { local($x) = @_; $x =~ s/^\s*//; $x =~ s/\s*$//; return $x; } sub basename { # Like basename(1), returns basename of a path. local($x) = @_; $x =~ s,/+$,,; # remove trailing /'s if ( $x =~ m,/([^/]+)$, ) { # check if matches / $x = $1; # grab stuff after the last / } $x = '.' if $x eq ''; # evidently input was null. return $x; } sub dirname { # Like dirname(1), returns dirname of a path. local($x) = @_; $x =~ s,/+$,,; # remove trailing /'s $x =~ s,/+,/,g; # change multiple /'s to single / if ( $x =~ m,/([^/]+)$, ) { # check if matches / $x = $`; # grab stuff before / $x = '/' if $x eq ''; # is root if null. } else { # it was a bare word without / $x = '.'; } $x = '.' if $x eq ''; # never return null string return $x; } sub fsleep { local($time) = @_; select(undef, undef, undef, $time) if $time; }