#!/usr/bin/perl -w # wmslashdot.pl v1.3, written by Jeff Meininger # http://rive.boxybutgood.com/WMHeadlines/ - jeffm@boxybutgood.com # # Original concept by Pascal Hofstee... # # # Proxy support based on code provided by Dan Gundlach... # # # Proper HTTP/1.1 calls by Kjeld Hoyer Mortensen... # # # wmslashdot is licensed under the GPL version 2. # wmslashdot is Copyright (C) 1999 by Jeff Meininger # # For setup information, please see the following URL... # http://rive.boxybutgood.com/WMHeadlines/ # # For configuration options, type 'wmslashdot.pl --help' # All options are available from the command line. # # NO NEED TO EDIT THIS FILE FOR CONFIGURATION PURPOSES! print "Sorry, this doesn't do anything yet..\n"; exit 0; require 5.002; use strict; use Socket; use File::Copy; # TODO: my ($upkey, $downkey, $enterkey) = ("E", "F", "G"); # TODO: my @sitenames = ("Slashdot", "Freshmeat", ...); # TODO: my @remotes = ("slashdot.org", "freshmeat.net", ...); # TODO: my @urls = ("/ultramode.txt", "/whatever.txt", ...); my $sitename = "Slashdot"; my $scriptname = "slashdot"; my $remote = 'slashdot.org'; my $url = "/ultramode.txt"; my @time = localtime(); my $garble = scalar(localtime); $garble =~ s/\W//g; my $randomcrap = rand(900); my ($iaddr, $paddr, $proto, $line, $menufile, $tmpfile, $newstring, $proxy); my ($twentyfour, $dayfirst, $proxyflag, $loudflag, $forceupdate) = (0)x5; my ($showdate, $newflag) = (1)x2; my ($frontpage, $deathtext, $datestring) = ("")x3; my $nspath = "netscape"; $menufile = "$ENV{'HOME'}/.$scriptname" . "menu"; my $port = 80; my $maxlength = 9999; my $ampmstring = "AM"; my $kick = "\n\n"; my $yearstring = "-" . ($time[5] + 1900); # get configuration from commandline my $i; for ($i = 0; $i < scalar(@ARGV); $i++) { if ($ARGV[$i] eq "--help") { print "\nlcd$scriptname.pl usage:\n"; print "[-proxy host port] - enables use over a proxy\n"; print "[-n] - prevents netscape from opening a new window for each headline\n"; print "[-frontpage top|bottom] - adds a persistant item for the $sitename frontpage.\n\tIt can be placed at the top or bottom of the menu.\n"; print "[-loud] - useful for debugging problems. Otherwise, the script exits quietly\n\tin the case of an error.\n"; print "[-24] - display time in 24 format instead of 12 AM/PM\n"; print "[-dayfirst] - display day before month (like 25-12-1999) in date.\n"; print "[-nodate] - do not display 'last updated' date in menu title.\n"; print "[-noyear] - do not display the year in the 'last updated' date.\n"; print "[-proxyfix] - proxy support not working? Try this.\n"; print "[-maxlength num] - items will not be shown with more than [num] letters.\n"; print "[-nspath /path/to/netscape/executable] - if your 'netscape' is not in the PATH\n\tused by Window Maker, you may specify the full pathname to the netscape\n\texecutable here.\n"; print "[-menufile /etc/X11/WindowMaker/menu.$scriptname] - if you want to store the\n\tmenu somewhere other than ~/.$scriptname" . "menu, specify the FULL\n\tpathname with this option. (Keep write permissions in mind...)\n"; print "[-forceupdate] - force the menu file to be written even if the headlines have\n\tnot changed. For example, a change in preference options will _NOT_\n\tbe visible without using this option.\n"; print "\n"; exit(); } elsif($ARGV[$i] eq "-proxy") { if ((!defined($ARGV[$i + 2])) || ($ARGV[$i + 1] =~ /^-/) || ($ARGV[$i + 2] =~ /^-/) || ($ARGV[$i + 2] =~ /\D/)) { print "Please use '-proxy proxy.yourisp.com 3128' or whatever is appropriate.\n"; exit(); } else { $proxyflag = 1; $proxy = $ARGV[$i + 1]; $port = $ARGV[$i + 2]; } } elsif($ARGV[$i] eq "-n") { $newflag = 0; } elsif($ARGV[$i] eq "-frontpage") { if ((!defined($ARGV[$i + 1])) || (($ARGV[$i + 1] ne "top") && ($ARGV[$i + 1] ne "bottom"))) { print "Please use '-frontpage top' or '-frontpage bottom' to enable this feature.\n"; exit(); } else { $frontpage = $ARGV[$i + 1]; } } elsif($ARGV[$i] eq "-loud") { $deathtext = "ERROR: Could not connect to remote site"; } elsif($ARGV[$i] eq "-24") { $twentyfour = 1; } elsif($ARGV[$i] eq "-dayfirst") { $dayfirst = 1; } elsif($ARGV[$i] eq "-nodate") { $showdate = 0; } elsif($ARGV[$i] eq "-noyear") { $yearstring = ""; } elsif($ARGV[$i] eq "-proxyfix") { $kick = "\r\n\r\n"; } elsif($ARGV[$i] eq "-maxlength") { if ((!defined($ARGV[$i + 1])) || ($ARGV[$i + 1] =~ /\D/)) { print "Please use '-maxlength NUM' where NUM is an integer, like 60.\n"; exit(); } else { $maxlength = $ARGV[$i + 1]; } } elsif($ARGV[$i] eq "-nspath") { if (!defined($ARGV[$i + 1]) || ($ARGV[$i + 1] !~ /^\//)) { print "Please use '-nspath /opt/netscape-4.5/netscape', or whatever is appropriate.\nNote... you must specify the FULL pathname.\n"; exit(); } $nspath = $ARGV[$i + 1]; } elsif($ARGV[$i] eq "-menufile") { if (!defined($ARGV[$i + 1]) || ($ARGV[$i + 1] !~ /^\//)) { print "Please use '-menufile /etc/X11/WindowMaker/menu.$scriptname', or whatever is\nappropriate. Note... you must specify the FULL pathname.\n"; exit(); } $menufile = $ARGV[$i + 1]; } elsif($ARGV[$i] eq "-forceupdate") { $forceupdate = 1; } } if ($newflag == 0) { $newstring = ""; } else { $newstring = ", new-window"; } if ($twentyfour > 0) { $ampmstring = ""; } else { if ($time[2] > 11) { $ampmstring = "PM"; } if ($time[2] > 12) { $time[2] = $time[2] - 12; } } if ($showdate > 0) { if ($dayfirst > 0) { $datestring = " [$time[3]-" . ($time[4] + 1) . "$yearstring, " . $time[2] . ":" . sprintf("%02d", $time[1]) . "$ampmstring]"; } else { $datestring = " [" . ($time[4] + 1) . "-$time[3]$yearstring, " . $time[2] . ":" . sprintf("%02d", $time[1]) . "$ampmstring]"; } } else { $datestring = ""; } # start the fun $tmpfile = "/tmp/$scriptname" . "menu$garble$randomcrap"; open(TMPFILE, ">$tmpfile"); print TMPFILE "\"$sitename Headlines$datestring\" MENU\n"; if ($frontpage eq "top") { print TMPFILE "\"$sitename Frontpage\" EXEC $nspath -remote 'openURL(http://$remote/$newstring)' || $nspath 'http://$remote/'\n"; } # network connection portion is pretty much stolen from 'man perlipc' if ($proxyflag > 0) { $iaddr = inet_aton($proxy) || wmdie($deathtext); } else { $iaddr = inet_aton($remote) || wmdie($deathtext); } $paddr = sockaddr_in($port, $iaddr); $proto = getprotobyname('tcp'); socket(SOCK, PF_INET, SOCK_STREAM, $proto) || wmdie($deathtext); connect(SOCK, $paddr) || wmdie($deathtext); select(SOCK); $| = 1; select(STDOUT); if ($proxyflag > 0) { print SOCK "GET http://$remote$url HTTP/1.1$kick"; } else { print SOCK "GET $url HTTP/1.1\nHost: $remote:80$kick"; } $i = 0; my $flag = 0; while (defined($line = )) { $i++; if ($line =~ /^%%/) { $i = 1; $flag = 1; } if ($flag > 0) { if ($i == 2) { chop($line); $line =~ s/"/'/g; # " Balances out quote... $line =~ s/<.*?>//g; $line =~ s/&.{1,5}?;//g; if (length($line) > $maxlength) { $line = substr($line, 0, $maxlength) . "..."; } print TMPFILE "\"$line\" EXEC $nspath -remote 'openURL("; } elsif ($i == 3) { chop($line); print TMPFILE "$line$newstring)' || $nspath '$line'\n"; } } } if ($frontpage eq "bottom") { print TMPFILE "\"$sitename Frontpage\" EXEC $nspath -remote 'openURL(http://$remote/$newstring)' || $nspath 'http://$remote/'\n"; } print TMPFILE "\"$sitename Headlines$datestring\" END\n"; close(SOCK) || die "Error closing socket: $!"; close(TMPFILE); # compare tmpfile with current menufile and possibly update it. if (-e $menufile) { my ($tmpline, $menuline, $linecount); open(MENUFILE, $menufile); open(TMPFILE, $tmpfile); # read in the first 'headline' menu entry from each file. if ($frontpage eq "top") { $linecount = 3; } else { $linecount = 2; } for ($i = 0; $i < $linecount; $i++) { if (eof(TMPFILE)) { if ($forceupdate == 0) { close(MENUFILE); close(TMPFILE); unlink($tmpfile); exit(); } } else { $tmpline = ; } unless (eof(MENUFILE)) { $menuline = ; } } if (($forceupdate == 0) && (($tmpline =~ /^"$sitename Headlines/) || ($tmpline =~ /^"$sitename Frontpage/) || ($tmpline eq $menuline))) { close(MENUFILE); close(TMPFILE); unlink($tmpfile); exit(); } } close(MENUFILE); close(TMPFILE); copy($tmpfile, $menufile); unlink($tmpfile); exit(); sub wmdie { my $string = shift; if ($string ne "") { print "$string\n"; } close(SOCK); close(TMPFILE); unlink($tmpfile); if ($string eq "") { exit(0); } else { exit(1); } }