webrowse (webrowse-1.7.3.tgz) | : | webrowse (webrowse-2.0.0.tgz) | ||
---|---|---|---|---|
#!/usr/bin/perl | #!/usr/bin/perl | |||
############################################################################### | ############################################################################### | |||
## Custom Configuration ####################################################### | ## Custom Configuration ####################################################### | |||
# It's unlikely that any of these should be changed, and if they are, | # It's unlikely that any of these should be changed, and if they are, update | |||
# update the man page as well. | # the man page as well. | |||
# default browser and cleanup rules | # default browser, interface and cleanup rules | |||
$use_ns = ($ENV{'WB_BROWSER'} =~ /mosaic/i) ? 0 : 1; | $browser = ($ENV{'WB_BROWSER'} =~ /chrom/i) ? 'c' : | |||
$use_sp = ($ENV{'WB_SLEEP'} =~ /at/i) ? 0 : 1; | ($ENV{'WB_BROWSER'} =~ /mosaic/i) ? 'm' : 'z'; | |||
$use_old = ($ENV{'WB_MOZOLD'} =~ /./) ? 1 : 0; | ||||
$use_sp = ($ENV{'WB_SLEEP'} =~ /at/i) ? 0 : 1; | ||||
# default browser command and directories for temporary files | # default browser command and directories for temporary files | |||
$netscape = $ENV{'WB_NETSCAPE'} || 'netscape'; | $chrome = $ENV{'WB_CHROME'} || 'chromium-browser'; | |||
$nstmp = $ENV{'WB_NSTMP'} || $ENV{'WB_TMP'} || | $mozilla = $ENV{'WB_MOZILLA'} || $ENV{'WB_NETSCAPE'} || 'firefox'; | |||
((-d "$ENV{'HOME'}/.mozilla") ? "$ENV{'HOME'}/.mozilla" : | $chtmp = $ENV{'WB_CHTMP'} || $ENV{'WB_TMP'} || | |||
(-d "$ENV{'HOME'}/.netscape") ? "$ENV{'HOME'}/.netscape" : | ((-d "$ENV{'HOME'}/.cache/chromium") | |||
(-d "$ENV{'HOME'}/tmp") ? "$ENV{'HOME'}/tmp" : '/tmp'); | ? "$ENV{'HOME'}/.cache/chromium" : | |||
$mstmp = $ENV{'WB_MSTMP'} || $ENV{'WB_TMP'} || | (-d "$ENV{'HOME'}/tmp") ? "$ENV{'HOME'}/tmp" : '/tmp'); | |||
((-d "$ENV{'HOME'}/tmp") ? "$ENV{'HOME'}/tmp" : '/tmp'); | $nstmp = $ENV{'WB_MZTMP'} || $ENV{'WB_NSTMP'} || $ENV{'WB_TMP'} || | |||
((-d "$ENV{'HOME'}/.mozilla") ? "$ENV{'HOME'}/.mozilla" : | ||||
(-d "$ENV{'HOME'}/.netscape") ? "$ENV{'HOME'}/.netscape" : | ||||
(-d "$ENV{'HOME'}/tmp") ? "$ENV{'HOME'}/tmp" : '/tmp'); | ||||
$mstmp = $ENV{'WB_MSTMP'} || $ENV{'WB_TMP'} || | ||||
((-d "$ENV{'HOME'}/tmp") ? "$ENV{'HOME'}/tmp" : '/tmp'); | ||||
# default umask, tmp file hold time, browser window and pwd command | # default umask, tmp file hold time, browser window and pwd command | |||
$umask = (defined $ENV{'WB_UMASK'}) ? $ENV{'WB_UMASK'} : 077; | $umask = (defined $ENV{'WB_UMASK'}) ? $ENV{'WB_UMASK'} : 077; | |||
$keep = (defined $ENV{'WB_KEEP'}) ? $ENV{'WB_KEEP'} : 10; | $keep = (defined $ENV{'WB_KEEP'}) ? $ENV{'WB_KEEP'} : 10; | |||
$id = $ENV{'WB_ID'}; | $id = $ENV{'WB_ID'}; | |||
$pwd = $ENV{'WB_PWD'} || 'pwd'; | $pwd = $ENV{'WB_PWD'} || 'pwd'; | |||
# hack to suppress browsers reducing font size when markup implies monospacing | # hack to suppress browsers reducing font size when markup implies monospacing | |||
# ala code.stephenmorley.org/html-and-css/\ | # ala code.stephenmorley.org/html-and-css/\ | |||
# fixing-browsers-broken-monospace-font-handling/ | # fixing-browsers-broken-monospace-font-handling/ | |||
$pres = ' STYLE="font-family: monospace, monospace; font-size: 1em"'; | $pres = ' STYLE="font-family: monospace, monospace; font-size: 1em"'; | |||
# extra custom mail quoting rules (modify $_) | # extra custom mail quoting rules (modify $_) | |||
sub mailquotecust { | sub mailquotecust { | |||
return unless ($ENV{'USER'} || $ENV{'LOGNAME'}) eq 'kinzler'; | return unless ($ENV{'USER'} || $ENV{'LOGNAME'}) eq 'kinzler'; | |||
local($cursive) = ' STYLE="font-family: Comic Sans, Comic Sans MS,' | local($cursive) = ' STYLE="font-family: Comic Sans, Comic Sans MS,' | |||
. ' cursive, serif"'; | . ' cursive, serif"'; | |||
local($small) = ' STYLE="font-size: .8em"'; | local($small) = ' STYLE="font-size: .8em"'; | |||
s/-sbk\b|\tSteve$/<SPAN$cursive>$&<\/SPAN>/mg; | s/-sbk\b|\tSteve$/<SPAN$cursive>$&<\/SPAN>/mg; | |||
s/(\n)((- ){34}-\n.*?)(?=$|\n\n)/$1<SPAN$small>$2<\/SPAN>$4/gs; | s/(\n)((- ){34}-\n.*?)(?=$|\n\n)/$1<SPAN$small>$2<\/SPAN>$4/gs; | |||
local($urlp) = '[^\s\'"`<>()\[\]{}]*'; | local($urlp) = '[^\s\'"`<>()\[\]{}]*'; | |||
s!<(https?://l\.facebook.com/$urlp?)>! $1 !gi; | ||||
s!\bhttps?://l\.facebook\.com/+l/+[^/]+/+($urlp)! | s!\bhttps?://l\.facebook\.com/+l/+[^/]+/+($urlp)! | |||
$_ = &urldecode($1), s#^[-\w.]+\.(com|net|org)#http://$&#i, $_!gie; | $_ = &urldecode($1), s#^[-\w.]+\.(com|net|org)#http://$&#i, | |||
"\n[FBLINK:]$_\n"!gie; | ||||
} | } | |||
@short = qw( slnm.us ); | @short = qw( slnm.us ); | |||
# URL shortening services as of 2014-10-26 from | # 68 URL shortening services as of 2015-02-27 from | |||
# www.hongkiat.com/blog/url-shortening-services-the-ultimate-list | # www.hongkiat.com/blog/url-shortening-services-the-ultimate-list | |||
push(@short, qw( | push(@short, qw( | |||
301url.com a2n.eu b65.us beam.to byinter.com canurl.com digbig.com | 301url.com a2n.eu b65.us beam.to byinter.com canurl.com digbig.com | |||
doiop.com dwarfurl.com easyurl.net fhurl.com fhurl.com | doiop.com dwarfurl.com easyurl.net fhurl.com fhurl.com | |||
fwdurl.net g8l.us get-shorty.com hongkiat.decenturl.com | fwdurl.net g8l.us get-shorty.com hongkiat.decenturl.com | |||
hongkiat.euro.st hongkiat.notlong.com hongkiat.shorturl.com | hongkiat.euro.st hongkiat.notlong.com hongkiat.shorturl.com | |||
is.gd lnk.in minilien.com moourl.com myurl.in nanoref.com | is.gd lnk.in minilien.com moourl.com myurl.in nanoref.com | |||
nutshellurl.com piurl.com redirx.com rubyurl.com shorl.com | nutshellurl.com piurl.com redirx.com rubyurl.com shorl.com | |||
shorterlink.com shortlinks.co.uk shredurl.com shrinkr.com | shorterlink.com shortlinks.co.uk shredurl.com shrinkr.com | |||
shrinkurl.us shrtnd.com shurl.net simurl.com smallr.com | shrinkurl.us shrtnd.com shurl.net simurl.com smallr.com | |||
skipping to change at line 72 | skipping to change at line 81 | |||
urlcutter.com urlhawk.com urltea.com urlvi.be wapurl.co.uk | urlcutter.com urlhawk.com urltea.com urlvi.be wapurl.co.uk | |||
www.6url.com www.ezurl.eu www.liteurl.net www.shortenurl.com | www.6url.com www.ezurl.eu www.liteurl.net www.shortenurl.com | |||
www.urlpire.com www.x.se xil.in xrl.us yatuc.com yep.it | www.urlpire.com www.x.se xil.in xrl.us yatuc.com yep.it | |||
you.ne1.net yourname.shim.net)); | you.ne1.net yourname.shim.net)); | |||
@short = grep(s/\./\\./g || 1, @short); | @short = grep(s/\./\\./g || 1, @short); | |||
############################################################################### | ############################################################################### | |||
## Usage ###################################################################### | ## Usage ###################################################################### | |||
# webrowse -- browse the given input in a local web browser, with markup | # webrowse -- browse the given input in a local web browser, with markup | |||
# Steve Kinzler, kinzler@cs.indiana.edu, May 96/Jan 98 | # Steve Kinzler, steve@kinzler.com, May 96/Jan 98/Feb 15 | |||
# see website http://www.cs.indiana.edu/~kinzler/webrowse/ | # see website http://kinzler.com/me/webrowse/ | |||
# http://www.cs.indiana.edu/~kinzler/home.html#web | # http://kinzler.com/me/home.html#web | |||
$VERSION = '1.7.3'; | $VERSION = '2.0.0'; | |||
use Getopt::Std; $Getopt::Std::STANDARD_HELP_VERSION = 1; | use Getopt::Std; $Getopt::Std::STANDARD_HELP_VERSION = 1; | |||
($Nnote, $Mnote) = ($use_ns) ? (' (default)', '') : ('', ' (default)'); | ($Cnote, $Nnote, $Mnote) = ($browser =~ /c/) ? (' (default)', '', '') : | |||
($Pnote, $Anote) = ($use_sp) ? (' (default)', '') : ('', ' (default)'); | ($browser =~ /z/) ? ('', ' (default)', '') : | |||
$usage = "usage: $0 [ -N | -M ] [ -s | -x | -mq | -u | -c ] | ('', '', ' (default)'); | |||
[ -k MINUTES ] [ -p | -a ] [ -i ID ] [ -w | -t ] [ -rnvo ] | $Onote = ($use_old) ? ' (default)' : ''; | |||
[ -h ] [ FILE ] | ($Pnote, $Anote) = ($use_sp) ? (' (default)', '') : ('', ' (default)'); | |||
-N use a Netscape or Mozilla (NS/Moz) browser$Nnote | $usage = "usage: $0 [ -C | -Z | -N | -M ] [ -O ] | |||
[ -s | -x | -mq | -u | -c ] [ -k MINUTES ] [ -p | -a ] [ -i ID ] | ||||
[ -w | -t ] [ -rnvo ] [ -h ] [ FILE ] | ||||
-C use a Chrome browser$Cnote | ||||
-Z,-N use a Mozilla (or Netscape) browser$Nnote | ||||
-M use a Mosaic browser$Mnote | -M use a Mosaic browser$Mnote | |||
-O use the old interface for Mozilla/Netscape$Onote | ||||
-s tag the standard input as HTML (default TEXT) | -s tag the standard input as HTML (default TEXT) | |||
-x tag the standard input as XML (default TEXT) | -x tag the standard input as XML (default TEXT) | |||
-m link markup a TEXT copy of the input for browsing (heuristic) | -m link markup a TEXT copy of the input for browsing (heuristic) | |||
-q quote markup a TEXT copy of the input for browsing | -q quote markup a TEXT copy of the input for browsing | |||
-u take the argument or stdin as a URL to browse | -u take the argument or stdin as a URL to browse | |||
-c take the argument or stdin as a remote command (NS/Moz only) | -c take the argument or stdin as a remote command (Mozilla only) | |||
-k minutes to keep any temporary input (default $keep) | -k minutes to keep any temporary input (default $keep) | |||
-p use a sleeping process to delete temporary input$Pnote | -p use a sleeping process to delete temporary input$Pnote | |||
-a use an at job to delete temporary input$Anote | -a use an at job to delete temporary input$Anote | |||
-i id of the window or process of the browser to use | -i id of the window or process of the browser to use (Mosaic only) | |||
-w open a new browser window, default use first existing window | -w open a new browser window, default use first existing window | |||
-t open a new browser tab (newer NS/Moz only) | -t open a new browser tab (not Mosaic) | |||
-r don't raise the browser window (NS/Moz only) | -r don't raise the browser window (old Mozilla only) | |||
-n don't actually use the browser at all | -n don't actually use the browser at all | |||
-v print the browser command to be run (NS/Moz only) | -v print the browser command to be run (not Mosaic) | |||
-o print the processed input to stdout | -o print the processed input to stdout | |||
-h just print this help message | -h just print this help message | |||
The NS/Moz command that will be used is `$netscape`. | The Chrome command that will be used is `$chrome`. | |||
The Mozilla command that will be used is `$mozilla`. | ||||
MINUTES is specified with an integer number or the word 'forever'. | MINUTES is specified with an integer number or the word 'forever'. | |||
Temporary copies of the input (from standard input and/or for markup) | Temporary copies of the input (from standard input and/or for markup) | |||
are stored in $nstmp (with NS/Moz) | are stored in $chtmp (with Chrome), | |||
or $mstmp (with Mosaic). | $nstmp (with Mozilla or $mstmp (with Mosaic). | |||
Version $VERSION\n"; | Version $VERSION\n"; | |||
# parse and check command line options | # parse and check command line options | |||
getopts('NMsxmquck:pai:wtrnvoh') || die $usage; | getopts('CZNMOsxmquck:pai:wtrnvoh') || die $usage; | |||
die "Invalid minutes: $opt_k\n", $usage unless $opt_k =~ /(^\d*$|forever)/i; | die "Invalid minutes: $opt_k\n", $usage unless $opt_k =~ /(^\d*$|forever)/i; | |||
die $usage if $opt_h || $opt_u && $opt_c; | die $usage if $opt_h || $opt_u && $opt_c; | |||
# let command line options override environmental defaults | # let command line options override environmental defaults | |||
$use_ns = ($opt_N) ? 1 : ($opt_M) ? 0 : $use_ns; | $browser = ($opt_C) ? 'c' : ($opt_Z || $opt_N) ? 'z' : | |||
$use_sp = ($opt_a) ? 0 : ($opt_p) ? 1 : $use_sp; | ($opt_M) ? 'm' : $browser; | |||
$keep = ($opt_k ne '') ? $opt_k : $keep; | $use_old = ($opt_O || $opt_N && ! $opt_Z) ? 1 : $use_old; | |||
$id = ($opt_i ne '') ? $opt_i : $id; | $use_sp = ($opt_a) ? 0 : ($opt_p) ? 1 : $use_sp; | |||
$cwd = ''; | $keep = ($opt_k ne '') ? $opt_k : $keep; | |||
$id = ($opt_i ne '') ? $opt_i : $id; | ||||
$cwd = ''; | ||||
############################################################################### | ############################################################################### | |||
## Execution ################################################################## | ## Execution ################################################################## | |||
# Note: we need the STDOUT/STDERR redirection in the system() call below | # Note: we need the STDOUT/STDERR redirection in the system() call below | |||
# to avoid waiting for WB_RUNURL termination | # to avoid waiting for WB_RUNURL termination | |||
# browse URLs, commands and files without markup straight-away and exit | # browse URLs, commands and files without markup straight-away and exit | |||
$url = (@ARGV) ? $ARGV[0] : <> . '', | $url = (@ARGV) ? $ARGV[0] : <> . '', | |||
$ENV{'WB_RUNURL'} && system("$ENV{'WB_RUNURL'} '$url' > /dev/null 2>&1 &"), | $ENV{'WB_RUNURL'} && system("$ENV{'WB_RUNURL'} '$url' > /dev/null 2>&1 &"), | |||
&browse($url, 'url'), exit if $opt_u; | &browse($url, 'url'), exit if $opt_u; | |||
&browse((@ARGV) ? $ARGV[0] : <> . '', 'cmd'), exit if $opt_c; | &browse((@ARGV) ? $ARGV[0] : <> . '', 'cmd'), exit if $opt_c; | |||
&browse(&abspath($ARGV[0]), 'exec'), exit if @ARGV | &browse(&abspath($ARGV[0]), 'exec'), exit if @ARGV | |||
&& ! ($opt_m || $opt_q); | && ! ($opt_m || $opt_q); | |||
# find a temporary filename to use | # find a temporary filename to use | |||
$tmpdir = ($use_ns) ? $nstmp : $mstmp; | $tmpdir = ($browser =~ /c/) ? $chtmp : ($browser =~ /z/) ? $nstmp : $mstm p; | |||
$ext = ($opt_x) ? '.xml' : ($opt_s || $opt_m || $opt_q) ? '.html' : '.txt'; | $ext = ($opt_x) ? '.xml' : ($opt_s || $opt_m || $opt_q) ? '.html' : '.txt'; | |||
$aa = ''; | $aa = ''; | |||
do { | do { | |||
$aa = ($aa) ? ++$aa : 'AA'; | $aa = ($aa) ? ++$aa : 'AA'; | |||
$tmp = "$tmpdir/webrowse${$}$aa$ext"; | $tmp = "$tmpdir/webrowse${$}$aa$ext"; | |||
} while -e $tmp; | } while -e $tmp; | |||
# open the temporary file, trapping signals for cleanup | # open the temporary file, trapping signals for cleanup | |||
umask $umask; | umask $umask; | |||
$SIG{'HUP'} = $SIG{'INT'} = $SIG{'PIPE'} = $SIG{'TERM'} = 'end'; | $SIG{'HUP'} = $SIG{'INT'} = $SIG{'PIPE'} = $SIG{'TERM'} = 'end'; | |||
skipping to change at line 214 | skipping to change at line 231 | |||
} | } | |||
############################################################################### | ############################################################################### | |||
## Subroutines ## Browser Remote Control ###################################### | ## Subroutines ## Browser Remote Control ###################################### | |||
# Direct the browser to load a given target or run a given command, | # Direct the browser to load a given target or run a given command, | |||
# and exit if requested. | # and exit if requested. | |||
sub browse { | sub browse { | |||
local($file, $arg) = @_; | local($file, $arg) = @_; | |||
chop($file) if $file =~ /\n$/; | chop($file) if $file =~ /\n$/; | |||
local($url, $flush, @args) = ($file, $|, ()); | local($url, $flush, $pid, @args) = ($file, $|, undef, ()); | |||
$url =~ s/^\"(.*)\"$/$1/, $url =~ s/^\'(.*)\'$/$1/, | $url =~ s/^\"(.*)\"$/$1/, $url =~ s/^\'(.*)\'$/$1/, | |||
$url =~ s/^\((.*)\)$/$1/, $url =~ s/^\<(.*)\>$/$1/, | $url =~ s/^\((.*)\)$/$1/, $url =~ s/^\<(.*)\>$/$1/, | |||
$url =~ s/^\[(.*)\]$/$1/, $url =~ s/^\{(.*)\}$/$1/ if $arg eq 'url'; | $url =~ s/^\[(.*)\]$/$1/, $url =~ s/^\{(.*)\}$/$1/ if $arg eq 'url'; | |||
$url = "file:$url" if $arg ne 'url' && $arg ne 'cmd'; | $url = "file:$url" if $arg ne 'url' && $arg ne 'cmd'; | |||
# construct the netscape/mozilla remote control command to run, | # construct the chrome/mozilla remote control command to run, | |||
# and print it if requested | # and print it if requested | |||
if ($use_ns) { | if ($browser =~ /[cz]/) { | |||
$url =~ s/\(/%28/g; $url =~ s/\)/%29/g; $url =~ s/,/%2C/g; | $url =~ s/\(/%28/g; $url =~ s/\)/%29/g; $url =~ s/,/%2C/g; | |||
# Mozilla 1.7b seems to need this: | if ($browser =~ /c/) { | |||
$url .= '/' if $url =~ /^https?:\/\/[-\w.]+(:\d*)?$/i; | push(@args, $chrome, ($opt_t) ? () | |||
$url .= ($opt_w) ? ', new-window' : | : '--new-window', $url); | |||
($opt_t) ? ', new-tab' : '' if $arg ne 'cmd'; | } elsif (! $use_old) { | |||
push(@args, $netscape); | push(@args, $mozilla, ($opt_t) ? '-new-tab' | |||
push(@args, '-id', $id) if $id; | : '-new-window', $url); | |||
push(@args, (($opt_r || $opt_w) ? '-noraise' : '-raise', | } else { | |||
'-remote', ($arg eq 'cmd') ? $url : "openURL($url)")); | # Mozilla 1.7b seems to need this: | |||
$url .= '/' if $url =~ /^https?:\/\/[-\w.]+(:\d*)?$/i; | ||||
$url .= ($opt_w) ? ', new-window' : | ||||
($opt_t) ? ', new-tab' :'' if $arg ne 'cmd'; | ||||
push(@args, $mozilla); | ||||
push(@args, '-id', $id) if $id; | ||||
push(@args, (($opt_r || $opt_w) ? '-noraise' :'-raise', | ||||
'-remote', ($arg eq 'cmd') ? $url | ||||
: "openURL($url)")); | ||||
} | ||||
$| = 1, print("@args\n"), $| = $flush if $opt_v; | $| = 1, print("@args\n"), $| = $flush if $opt_v; | |||
} | } | |||
# Note: newer mozilla software includes mozila-xremote-client | # Note: newer mozilla software includes mozilla-xremote-client | |||
# for a similar alternative interface that allows one to specify | # for a similar alternative interface that allows one to specify | |||
# the browser application. See www.mozilla.org/unix/remote.html | # the browser application. See www.mozilla.org/unix/remote.html | |||
# Note: with version 36.0, it seems, firefox no longer supports | ||||
# the netscape remote control interface, though it has another | ||||
# command line interface, which we now use as the default. | ||||
# if requested, | # if requested, | |||
# print the input and/or exit without any browser interaction | # print the input and/or exit without any browser interaction | |||
system(($arg eq 'url' || $arg eq 'cmd') ? 'echo' : '/bin/cat', $file) | system(($arg eq 'url' || $arg eq 'cmd') ? 'echo' : '/bin/cat', $file) | |||
if $opt_o; | if $opt_o; | |||
($arg) ? exit : return if $opt_n; | ($arg) ? exit : return if $opt_n; | |||
# remote control the browser | # remote control the browser | |||
# with NS/Moz, by running or execing the remote control command | # with Chrome/Mozilla, by running or execing the remote control command | |||
# with Mosaic, by writing a standard temporary command file and | # with Mosaic, by writing a standard temporary command file and | |||
# signaling the pid of the browser process, read from ~/.mosaicpid | # signaling the pid of the browser process, read from ~/.mosaicpid | |||
if ($use_ns) { | local($msg) = "$0: remote commands only available with old Mozilla" | |||
. " or Netscape\n"; | ||||
if ($browser =~ /c/ || $browser =~ /z/ && ! $use_old) { | ||||
die $msg if $arg eq 'cmd'; | ||||
exit unless defined($pid = fork) && $pid == 0; # parent exits | ||||
close STDOUT; # suppress "... in existing browser session." | ||||
($arg) ? exec @args : system @args; | ||||
} elsif ($browser =~ /z/) { | ||||
($arg) ? exec @args : system @args; | ($arg) ? exec @args : system @args; | |||
} else { | } else { | |||
die "$0: remote commands only available with Netscape" . | die $msg if $arg eq 'cmd'; | |||
" or Mozilla\n" if $arg eq 'cmd'; | ||||
unless ($id) { | unless ($id) { | |||
$pid = "$ENV{'HOME'}/.mosaicpid"; | $pid = "$ENV{'HOME'}/.mosaicpid"; | |||
$id = <PID>, close PID if open(PID, "< $pid"); | $id = <PID>, close PID if open(PID, "< $pid"); | |||
$id =~ s/\D.*//; | $id =~ s/\D.*//; | |||
die "$0: cannot get pid from $pid ($!)\n" if ! $id; | die "$0: cannot get pid from $pid ($!)\n" if ! $id; | |||
} | } | |||
$pid = "/tmp/Mosaic.$id"; | $pid = "/tmp/Mosaic.$id"; | |||
open(PID, "> $pid") || die "$0: cannot open $pid ($!)\n"; | open(PID, "> $pid") || die "$0: cannot open $pid ($!)\n"; | |||
print PID ($opt_w) ? 'newwin' : 'goto', "\n$url\n"; | print PID ($opt_w) ? 'newwin' : 'goto', "\n$url\n"; | |||
close PID; | close PID; | |||
End of changes. 29 change blocks. | ||||
59 lines changed or deleted | 94 lines changed or added |