Article 9857 of comp.lang.perl:
Xref: feenix.metronet.com comp.infosystems.www:6285 comp.lang.perl:9857 rec.arts.comics.strips:2686
Newsgroups: comp.infosystems.www,comp.lang.perl,clari.net.talk,rec.arts.comics.strips
Path: feenix.metronet.com!news.utdallas.edu!wupost!galileo.cc.rochester.edu!ub!news.kei.com!sol.ctr.columbia.edu!howland.reston.ans.net!vixen.cso.uiuc.edu!news.acns.nwu.edu!news.eecs.nwu.edu!jmyers
From: jmyers@eecs.nwu.edu (Jennifer Myers)
Subject: ANNOUNCE: CGI Script for Dilbert
Message-ID: <CJsKBC.M30@eecs.nwu.edu>
Sender: usenet@eecs.nwu.edu
Supersedes: <CJr5qJ.3I7@eecs.nwu.edu>
Organization: Northwestern University, Evanston, Illinois
Date: Mon, 17 Jan 1994 20:45:11 GMT
Lines: 398

This article supersedes the announcement of "dilbert," version 0.1.
I've been informed that the script cannot be named "dilbert" because
it is a registered trademark.  Therefore, I announce version 0.11 of
"read-comics".  Please update your version.

Thanks!

Announcing Version 0.11 of 'read-comics', a Common Gateway Interface
World Wide Web gateway to clari.feature.dilbert.  

'read-comics' is a Common Gateway Interface (CGI) script for
CGI-compliant HTTP (World Wide Web) servers (e.g., NSCA httpd 1.0).
'read-comics' generates a hypertext interface to the
clari.feature.dilbert newsgroup.  It does this by querying the NNTP
server for a list of active articles in the clari.feature.dilbert
newsgroup and then generates from this, a list of hyperlinks.  When a
link is selected, the article is retrieved from the NNTP server and
then uudecoded on-the-fly.

There is a special link: http://www-server.domain/cgi-bin/read-comics?today 
which will always point to the most recent comic strip.  

Connecting hosts not in the specified domain are denied access.  

Retrieval instructions:

    Version 0.11 of 'read-comics' is appended to the end of this article.
    The latest version of 'read-comics' may also be retrieved from the WWW as
        http://www.eecs.nwu.edu:8001/jmyers/cgi-src/read-comics
    or by anonymous ftp as
        eecs.nwu.edu:/pub/jmyers/cgi-src/read-comics

Installation:

    Configure $domain, $nntphost, and $group as appropriate.

    Put this script in your CGI bin directory.  For example, on my 
       server, I have this script installed as: 
       http://www.eecs.nwu.edu:8001/cgi-bin/read-comics


Acknowledgments:

    The NNTP code is adopted from code for a NNTP client written by 
        Eric Young <eay@psych.psy.uq.oz.au>
    The uudecode algorithm comes from _Programming_Perl_, 
        (Wall/Schwartz), p. 198.

Revision History:

1/17/94:      Version 0.11. Changed name of script to not interfere
              with trademark restrictions. (Dilbert is a registered
              trademark of Scott Adams and United Media).
              
1/16/94:      Version 0.1. Initial release.

Please contact me by email if you have any difficulties installing or
using this package.

Thanks,
-Jennifer

-- 
<A HREF = "http://www.eecs.nwu.edu:8001/jmyers/plan.html">Jennifer Myers</A>
jmyers@eecs.nwu.edu

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  read-comics
# Wrapped by jmyers@marigold on Mon Jan 17 14:35:00 1994
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'read-comics' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'read-comics'\"
else
echo shar: Extracting \"'read-comics'\" \(9256 characters\)
sed "s/^X//" >'read-comics' <<'END_OF_FILE'
X#!/usr/local/bin/perl
X#
X# read-comics
X#
X# Version 0.11, (January 17, 1994)
X# 
X# Author: Jennifer Myers <jmyers@eecs.nwu.edu>
X#
X# 'read-comics' is a Common Gateway Interface (CGI) script for CGI-compliant 
X# HTTP servers (e.g., NSCA httpd 1.0).  'read-comics' generates a hypertext 
X# interface to the clari.feature.dilbert newsgroup.  It does this by 
X# querying the NNTP server for a list of active articles in the 
X# clari.feature.dilbert newsgroup and then generates from this, a list of 
X# hyperlinks.  When a link is selected, the article is retrieved from the 
X# NNTP server and then uudecoded on-the-fly.
X#
X# There is a special link: http://www-server.domain/cgi-bin/read-comics?today 
X# which will always point to the most recent comic strip.
X#
X# Connecting hosts not in $domain are denied access.
X#
X# Retrieval instructions:
X#
X#    The latest version of 'read-comics' may be retrieved from the WWW as
X#	http://www.eecs.nwu.edu:8001/jmyers/cgi-src/read-comics
X#    or by anonymous ftp as
X#	eecs.nwu.edu:/pub/jmyers/cgi-src/read-comics
X#
X# Installation:
X#
X#    Configure $domain, $nntphost, and $group as appropriate.
X#
X#    Put this script in your CGI bin directory.  For example, on my 
X#       server, I have this script installed as: 
X#       http://www.eecs.nwu.edu:8001/cgi-bin/read-comics
X#
X# Acknowledgements:
X#
X#   The NNTP code is adopted from code for a NNTP client written by 
X# 	Eric Young <eay@psych.psy.uq.oz.au>
X#   The uudecode algorithm comes from _Programming_Perl_, 
X#	(Wall/Schwartz), p. 198.
X#
X# Revision History:
X#
X# 1/17/94:	Version 0.11. Changed name of script to not interfere
X#		with trademark restrictions. (Dilbert is a registered
X#		trademark of Scott Adams and United Media).
X#		
X# 1/16/94:	Version 0.1. Initial release.
X#
X#######################################################################
X
X# Change these variables to suit your environment.
X$domain = "nwu.edu";
X$nntphost = "news.acns.nwu.edu";
X$group = "clari.feature.dilbert";
X
X# You should not need to change anything after this line.
X$date = `/bin/date`;
X$query_string = $ENV{'QUERY_STRING'};
X$remote_host = $ENV{'REMOTE_HOST'};
X$script_name = $ENV{'SCRIPT_NAME'};
X
Xrequire 'sys/socket.ph';
X
Xif ($remote_host =~ /\.$domain$/) {
X	do startnntp("$nntphost");
X	do read_nntp_header();
X	($first, $last) = &group_cmd();
X	do xhdr_cmd($first,$last);
X}
X
Xif ($query_string eq "") { # Make index
X	print <<"EOM";
XContent-Type: text/html
X
X	<HTML><HEAD><TITLE>read-comics, a gateway to clari.feature.dilbert
X	</TITLE></HEAD>
X	<BODY><H1>clari.feature.dilbert gateway</H1><DL><HR>
X	Please note that the <EM>Dilbert</EM> comic strip is copyrighted by
X	United Media, and you may not pass copies to others.  Access to the
X	<EM>Dilbert</EM> comic strip is restricted to hosts in the
X	<STRONG>$domain</STRONG> domain.
X	<P>See <A HREF = "ftp://ftp.clarinet.com/help/dilbert"\
X	>ftp.clarinet.com:help/dilbert</A> for more information. <HR>
XEOM
X
X	if ($remote_host =~ /\.$domain$/) { # Access permitted
X		do getlinks(@subject);
X	} else { # Deny access
X		print <<"EOM";
X		<H2>Access Restricted:</H2>
X		Your host is not recognized as belonging in the 
X		<STRONG>$domain</STRONG> domain.  Copyright restrictions 
X		limit our distribution of this comic strip to hosts in the 
X		<STRONG>$domain</STRONG> domain. <P> <A HREF = 
X		"http://www.eecs.nwu.edu:8001/jmyers/cgi-src/read-comics"\
X		><EM>read-comics</EM></A>, a gateway to the newsgroup
X		<EM>clari.feature.dilbert</EM>, is a Common Gateway Interface 
X		(<A HREF="http://hoohoo.ncsa.uiuc.edu/cgi/overview.html"\
X		>CGI</A>) script, written in <A HREF = 
X		"http://www.eecs.nwu.edu:8001/perl.html">Perl</A>, which 
X		queries the news server via NNTP, generates a list of 
X		hyperlinked articles, and retrieves and uudecodes selected 
X		articles on-the-fly.
XEOM
X	}
X
X	print <<"EOM";
X	<HR>
X	This page was automatically generated on $date <HR>
X	This script, <A HREF = 
X	"http://www.eecs.nwu.edu:8001/jmyers/cgi-src/read-comics"\
X	><EM>read-comics</EM></A>, was written by <EM><A HREF = 
X	"http://www.eecs.nwu.edu:8001/jmyers/plan.html">Jennifer Myers</A>
X	</EM></BODY></HTML>
XEOM
X
X} else { # Query provided
X	if ($remote_host =~ /\.$domain$/) { # Access permitted
X		print STDOUT "Content-Type: image/gif\n\n";
X
X		if ($query_string eq "today") {
X			$query_string = $last;
X		}
X
X		@txt=&body_cmd($query_string); 
X
X		#
X		# uudecode algorithm
X		#
X		$_=shift(@txt) until ($mode,$file)=/^begin\s*(\d*)\s*(\S*)/;
X		while ($_ = shift(@txt)) {
X		        last if /^end/;
X		        next if /[a-z]/;
X		        next unless int((((ord() - 32) & 077) + 2) / 3) ==
X		                int(length() / 4);
X		        print unpack("u", $_);
X		}
X	} else { # Deny access
X
X	print <<"EOM";
XContent-Type: text/html
X
X	<HTML><HEAD><TITLE>Access Denied</TITLE></HEAD>
X	<BODY><H1>Access Denied</H1><HR>
X	Sorry!  The <EM>Dilbert</EM> comic is distributed by ClariNet.  
X	Copyright restrictions limit our distribution of this comic strip to 
X	hosts in the <STRONG>$domain</STRONG> domain. <P> <A HREF = 
X	"http://www.eecs.nwu.edu:8001/jmyers/cgi-src/read-comics"\
X	><EM>read-comics</EM></A>, a gateway to the newsgroup
X	<EM>clari.feature.dilbert</EM>, is a Common Gateway Interface (<A 
X	HREF= "http://hoohoo.ncsa.uiuc.edu/cgi/overview.html">CGI</A>) 
X	script, written in <A HREF = "http://www.eecs.nwu.edu:8001/perl.html"\
X	>Perl</A>, which queries the news server via NNTP, generates a list 
X	of hyperlinked articles, and retrieves and uudecodes selected 
X	articles on-the-fly. <HR> This script, <A HREF = 
X	"http://www.eecs.nwu.edu:8001/jmyers/cgi-src/read-comics"\
X	><EM>read-comics</EM></A>, was written by <EM><A HREF = 
X	"http://www.eecs.nwu.edu:8001/jmyers/plan.html">Jennifer Myers</A>
X	</EM></BODY></HTML>
XEOM
X	}
X} # End of main program
X
Xsub getlinks {
X        local(@articles) = @_;
X        local(@i);
X	print STDOUT "<UL><LI><A HREF =
X		\"http:$script_name?today\"\
X		>Today's Dilbert</a> (see below for title)</UL>";
X	print STDOUT "<H2>Archived:</H2>";
X	print STDOUT "<UL>";
X        while ($_=shift(@articles)) {
X                split;
X                $num=shift(@_);
X		@subj=@_;
X		if (@subj[0] eq "Dilbert:")  {
X	                print STDOUT "<LI> <A HREF=
X				\"http:$script_name?$num\">@subj</A>";
X		}
X        }
X	print STDOUT "</UL>";
X}
X
Xsub body_cmd {
X        local($name)=@_;
X        local(@ret);
X		
X        print NNTP "BODY $name\n";
X        $_=<NNTP>;
X        if (!/^222 /)
X                {
X#               print STDOUT "body cmd problems ($name):$_";
X                do quit_cmd(1);
X                }
X        @ret=&getlines();       
X        return(@ret);
X        }
X
Xsub xhdr_cmd {
X        local($a,$b)=@_;
X
X        print NNTP "XHDR Subject $a-$b\n";
X        $_=<NNTP>;
X        if (!/^221 /) {
X#               print STDOUT "xhdr cmd problems\n";
X                if (/^500 /) {
X                        do manual_xhdr_cmd($a,$b);
X                } else {
X                        do quit_cmd();
X		}
X                return;
X        }
X        @subject=&getlines();      
X}
X
Xsub manual_xhdr_cmd {
X        local($a,$b)=@_;
X        local($i,@s,$j);
X
X        $#subject=$[;
X        foreach $i ($a .. $b) {
X                print NNTP "HEAD $i\n";
X                $_=<NNTP>;
X	        if (/^221 /) {
X                        @s=grep(/^Subject: /,&getlines());
X#                       print STDOUT "no Subject: line in article $i\n"
X#                               if ($#s < 0);
X                        $s[0] =~ /^Subject: (.*)/;
X                        push(@subject,"$i $1");
X                } else {
X                        print "$_";
X                }
X        }
X}
X
Xsub getlines {
X        local(@ret);
X
X        while (<NNTP>) {
X                if (/^\./ && (!/^\.\./)) {
X                        chop;
X                        last;
X                }
X                s/\015//g;
X                push(@ret,$_);
X        }
X        return(@ret);
X}
X
Xsub quit_cmd {
X        local($code)=@_;
X        print NNTP "QUIT\n";
X        $_=<NNTP>;
X#       print STDOUT "close bad:$_" unless (/^205 /);
X        exit($code);
X}
X
Xsub group_cmd {
X        print NNTP "GROUP $group\n";
X        $_=<NNTP>;
X
X        split;
X        ($code,$num,$first,$last,$group)=@_;
X        if ($code != 211) {
X#               print STDOUT "group cmd problems:$_";
X                do quit_cmd(1);
X        }
X        return($first,$last);
X}
X
Xsub dokill {
X        kill(9,$child) if $child;
X}
X
Xsub startnntp {
X        local($name)=@_;
X
X        $SIG{'INT'}='dokill';
X
X        $sockaddr='Sna4x8';
X        chop($hostname=`hostname`);
X
X        ($n,$aliases,$proto)=getprotobyname('tcp');
X        ($n,$aliases,$port)=getservbyname('nntp','tcp');
X        ($n,$aliases,$type,$len,$thisaddr)=gethostbyname($hostname);
X        ($n,$aliases,$type,$len,$thataddr)=gethostbyname($name);
X        $this=pack($sockaddr,&AF_INET,0,$thisaddr);
X        $that=pack($sockaddr,&AF_INET,$port,$thataddr);
X
X        socket(NNTP,&PF_INET,&SOCK_STREAM,$proto) || die "socket: $!";
X        bind(NNTP,$this) || die "bind: $!";
X        connect(NNTP,$that) || die "connect: $!";
X
X        select(NNTP); $|=1;
X        select(STDIN); $|=1;
X        select(STDOUT); $|=1;
X}
X
Xsub read_nntp_header {
X        while (<NNTP>) {
X                last if (/^200 /);
X                last if (/^201 /);
X                exit(1) if (/^400 /);
X        }
X}
END_OF_FILE
if test 9256 -ne `wc -c <'read-comics'`; then
    echo shar: \"'read-comics'\" unpacked with wrong size!
fi
chmod +x 'read-comics'
# end of 'read-comics'
fi
echo shar: End of shell archive.
exit 0


