#/usr/local/bin/perl #Subject: Weather PERL Script #Reply-To: gregor@kafka.saic.com # # #Here is slightly modified version of the perl script posted #on the tenth. I have added a super simple help facility #which simply spits out the internal man page added in by #rouilj@cs.umb.edu. This option is -h. # # gregg hanna # gregor@kafka.saic.com # #------cut here-------------------------------cut here----------- # #/usr/local/bin/perl 'di'; 'ig00'; # # 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. # # Modified by rouilj@cs.umb.edu October 9, 1992. Changed pattern to # match almost all "type return to continue" type lines. Hopefully the # entire report will be presented to the user now. Also added flags # that allow selection of the info to get from the weather server. In # addition added code that makes use of the menu bypass ability, and # allows supression of the 24 line scroll restriction. Added the -q # flag that can be used to list (query) the three letter abbreviations # for all weather reporting sites within a state. In addition changed # the default city to be Boston ;-). Also crafted (crufted??) together # a rudimentary man page, and encapsulated it into the weather script. # # Modified by gregor@kafka.saic.com October 26, 1992. Added the -h # flag for help. Formats the script's man page. Also changed the # default city to be San Diego. require "getopts.pl"; $SERVER = "downwind.sprl.umich.edu"; $PORT = "3000"; $show_what = "+"; # this turns off the 24 line scroll restriction. # # Parse argument, if any # &Getopts("hufcemsqD"); $CITY = $ARGV[0]; if ($CITY eq "") { $CITY = "DFW"; # THIS IS THE DEFAULT CITY!!!!!!!!!!! } if (defined($opt_q)) { die "Can only use 2 letter state abbreviations with -q, exited" if (length($CITY) > 2); } if (defined($opt_h)) { system "nroff -man $0 | more"; exit 1; } $whichinfo_opts++, $show_what = "u" if defined($opt_u); $whichinfo_opts++, $show_what = "f" if defined($opt_f); $whichinfo_opts++, $show_what = "c" if defined($opt_c); $whichinfo_opts++, $show_what = "e" if defined($opt_e); $whichinfo_opts++, $show_what = "m" if defined($opt_m); $whichinfo_opts++, $show_what = "s" if defined($opt_s); die "Only one of -ufcems can be used, exiting" if $whichinfo_opts > 1; # # 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? $USMENU = 0; # See US 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 print $curline . "\n" if defined($opt_D); # # 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 } elsif (defined($opt_q)) { printf SOCK "\n"; # For query, go via main menu } else { printf SOCK "%s%s\n", $CITY, $show_what; # 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 } } elsif (defined $opt_q) { if (!$MAINMENU) { # At main menu, select Canadian forecasts $MAINMENU = 1; printf SOCK "1\n"; # US menu is item 1!! $curline = ""; } elsif (!$USMENU) { # At Canadian menu, select region $USMENU = 1; printf SOCK "3\n"; $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 =~ / Enter 2-letter state code: /) { printf SOCK "%s\n", $CITY; &showiton("Weather Sites"); $curline = ""; } } # # 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 @_; } ############################################################### # These next few lines are legal in both Perl and nroff. .00; # finish .ig 'di \" finish diversion--previous line must be blank .nr nl 0-1 \" fake up transition to first page again .nr % 0 \" start at page 1 '; __END__ ##### From here on it's a standard manual page ##### .TH WEATHER 1 "October 9, 1992" .SH NAME weather \- query the weather server for weather info .SH SYNOPSIS .B weather .RB [ \-ufcems ] [ three_letter_city_code ] .PP .B weather .RB [ \-q ] two_letter_state_code .PP .SH DESCRIPTION This command queries the weather database server run by the University of Michigan. By default it gets the weather service report for the Boston, Massachusetts area. .PP The arguments it takes are a US state abbreviation, or a three letter US Weather Service site abbreviation. If given a state abbreviation, the regional weather information is provided. If given a three letter site abbreviation, a weather report usually consisting of the 1-2 day forecast, the extended forecast, any special weather advisories, and climatic data is presented. Some of the above sections may not be available for a given weather site. The options can be used to select subsets of the presented data. .IP .B \-u This option eliminates the climate data from the report. .IP .B \-f Restricts the output to the 1-2 day forcast. .IP .B \-c Provide only the climatic data. .IP .B \-e Provide only the extended forcast data. .IP .B \-s Provide only the special advisory reports. .IP .B \-m Provide the marine report if available. .IP .B \-q This option can only be used with a two letter state abbreviation, and it produces a list of all of the three letter site codes for the state. .PP The entire program is written in perl. .SH ENVIRONMENT No environment variables are used. .SH FILES None. .SH "SEE ALSO" perl(1).