From: yanoff@csd4.csd.uwm.edu (Scott A. Yanoff)
Subject: Forecast shell script
Originator: yanoff@csd4.csd.uwm.edu
Organization: University of Wisconsin - Milwaukee, WI
Date: Fri, 24 Jul 1992 14:26:56 GMT

I have also decided to post this nifty shell script which will contact
Umich's Weather Underground for you quickly and automatically....
Save it as "forecast" and you can do:
"forecast wi"  to get a forecast of wisconsin, or use any two letter
  state code.

"forecast mke"  to get a forecast of Milwaukee, or use any three letter
   city code.

Keep in mind that if you just type "forecast" then the default city it will
lookup will be Milwaukee, but you can find it in the program below and
edit it to whatever default city you want it to be.

#!/usr/local/bin/perl
#
# A perl script to connect to the 'weather server' at
# Michigan and get the forcast for whatever city
# you want (3 letter code -- columbus 'cmh' by default).
#
# Alternatively, you can get the current information for
# a state if you enter a 2 letter code.
#
# Thanks to J Greely for the original network code, and
# Tom Fine for assistance and harassment.
#
# Copyright 1991 Frank Adelstein.  All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this
# software is hereby granted without fee, provided that
# the copyright notice and permission notice are not removed.
#
# --FNA 6/28/91
#
# Hacked by George Ferguson (ferguson@cs.rochester.edu) to include
# Canadian forecasts by zone number.
#
# Modified by gf for new weather service menus, 26 Jun 1992.
# I ripped lots of stuff out of this version, some of it may have to be
# put back, but it works fine for me.
# It's much easier to navigate the system now (for US forecasts, anyway),
# so the interaction loop is considerably simplified. The Canadian stuff
# is relatively straightforward also.
#

$SERVER = "downwind.sprl.umich.edu";
$PORT   = "3000";

#
# Parse argument, if any
#
$CITY = $ARGV[0]; 
if ($CITY eq "") {
    $CITY = "mke";		# THIS IS THE DEFAULT CITY!!!!!!!!!!!
}

#
# Allow 4-char symbolic names for Canadian reports.
#
%canNames = ("salt","1",  "SALT","1",
	     "calt","2",  "CALT","2",
	     "nalt","3",  "NALT","3", "nebc","3", "NEBC","3",
	     "cobc","4",  "COBC","4",
	     "inbc","5",  "INBC","5",
	     "sman","6",  "SMAN","6",
	     "nman","7",  "NMAN","7",
	     "nova","8",  "NOVA","8",
	     "pedi","9",  "PEDI","9",
	     "newb","10", "NEWB","10",
	     "labr","11", "LABR","11",
	     "nfld","12", "NFLD","12",
	     "sont","13", "SONT","13",
	     "nont","14", "NONT","14",
	     "nwon","15", "NWON","15",
	     "ssas","16", "SSAS","16",
	     "nsas","17", "NSAS","17",
	     "yukn","18", "YUKN","18",
	     "sque","19", "SQUE","19", "ottw","19", "OTTW","19",
	     "nque","20", "NQUE","20");              
#
# If we're given one of these names, use the number instead.
#
if ($t=$canNames{$CITY}) {
    $CITY = $t;
}

#
# Check argument
#
if ($CITY =~ /[0-9]+/) {
    $ISCAN = 1;
} elsif (length ($CITY) == 3 ) {
    $ISCAN = 0;
} elsif (length ($CITY) == 2 ) {
    $ISCAN = 0;
} else {
    print "Must be either a 2 letter state code or 3 letter city code.\n";
    print "Can also be a numeric Canadian zone number or symbolic name.\n";
    exit (1);
}

#
# Connect to the server
#
local($sockaddr,$here,$there,$response,$tries) = ("Snc4x8");
$here  = pack($sockaddr,2,0,&getaddress("localhost"));
$there = pack($sockaddr,2,$PORT,&getaddress($SERVER));
print "\nConnecting to $SERVER.";
die "socket: $!\n" if (!socket(SOCK,2,1,6));
print ".";
die "connect: $!\n" if (!connect(SOCK,$there));
print ".connected\n";
select(SOCK); $| = 1;
select(STDOUT); $| = 1;       # make unbuffered

#
# Initialize
#
$SHOWIT = 0;			# Should we print?
$MAINMENU = 0;			# Seen main menu once already?
$CANMENU = 0;			# See Canadian menu once already?

#
# Interact...
#
while (read(SOCK,$c,1)) {	# Get a character
    if ($c eq "\n") {		# Newline -> maybe print, start new line
	if ($SHOWIT == 1) {
	    print $curline, "\n";
	}
	$curline = "";
	next; 
    }
    if ($c eq "\r") { next; }	# Return -> ignore
    $curline .= $c;		# Else add char to current line
	
    #
    # Now test the current line so far to see what action to take, if any.
    #
    if ($curline =~ /Press Return for menu, or enter 3 letter forecast city code:/) { # At first prompt...
	if ($ISCAN) {
	    printf SOCK "\n";	# For Canadian forecast, go via main menu
	} else {
	    printf SOCK "%s\n", $CITY; # For US, bypass menu
	    $curline = "";
	    &showiton("us city/state");
	}
    } elsif ($curline =~ / Selection:/) { # In main menu...
	if ($ISCAN) {		# Canadian forecast...
	    if (!$MAINMENU) {	    # At main menu, select Canadian forecasts
		$MAINMENU = 1;
		printf SOCK "2\n";  # Canadian forecast is item 2!!
		$curline = "";
	    } elsif (!$CANMENU) {   # At Canadian menu, select region
		$CANMENU = 1;
		printf SOCK "%s\n", $CITY;
		&showiton("canadian region");
		$curline = "";
	    } else {
		printf SOCK "X\n";  # Otherwise exit
	    }
	} else {
	    printf SOCK "X\n";	# Otherwise exit
	}
    } elsif ($curline =~ / Invalid 3-letter city code./) {
	printf SOCK "X\n";
	printf "%s is an invalid 3 letter city code.\n", $CITY;
	&showitoff("3-letter");
    } elsif ($curline =~ / Invalid city or state code./) {
	printf SOCK "X\n";
	printf "%s is an invalid city or state code.\n", $CITY;
	&showitoff("invalid");
    } elsif ($curline =~ / CITY FORECAST MENU/) {
	&showitoff("city forecast");
    } elsif ($curline =~ / CURRENT WEATHER MENU/) {
	&showitoff("city forecast");
    } elsif ($curline =~ / CANADIAN FORECASTS/) {
	&showitoff("canadian forecasts");
    } elsif ($curline =~ / Press Return to continue: /) {
	printf SOCK "\n";
	$curline = "";
	&showiton("Return to continue");
    } elsif ($curline =~ / Press Return to continue printing or M to return to menu: /) {
	printf SOCK "\n";
	$curline = "";
	&showiton("Return to continue printing");
    }
}

#
# Clean up and done
#
close(SOCK);
exit(0);

#####################################################

sub getaddress {
    local($host) = @_;
    local(@ary);
    @ary = gethostbyname($host);
    return(unpack("C4",$ary[4]));
}

sub showitoff {
    local($txt) = @_;
    &maybeprint ("showit off ($txt)\n");
    $SHOWIT = 0;
}

sub showiton {
    local($txt) = @_;
    &maybeprint ("showit on ($txt)\n");
    $SHOWIT = 1;
}

sub maybeprint {
#    print @_;
}
-- 
 _/\ _ !\ _         @           Milwaukee, WI - A Great Place by a Great Lake
!  _! !! ! !_  ~~  @ ~  ~~         
! ! ! !! ! ! !~~__=||_~ ~~~          *** Computing Services Division ***
! ! ! _! ! ~~~ ~\____/  ~~~ yanoff@csd4.csd.uwm.edu   yanoff@elvis.csd.uwm.edu