This site should appear as the creator intended if viewed in Explorer 3.0 or higher.  Netscape should be OK too.  Users of other browsers are up a creek and must paddle as best they can.

The existence of this page is in no way intended to express support for the dangerous and unbecoming habit of smoking, a practice that results in an untimely and agonizing death for many among its adherents.

This is the cyber home of the late Willie the KOOL penguin.

Years (indeed, decades) before "Joe Camel" became a controversial cartoon representative of the tobacco industry, "Willie" was a widely known symbol and spokes-penguin for KOOL cigarettes.

During a 31-year period bracketing the Second World War, Willie appeared in magazine ads, television commercials, and even as a little imprint on the cigarettes themselves.   His image was also seen in a wide variety of merchandising spin-offs, including three-dimensional figurines, the best known of which are the "Willie" and "Millie" salt and pepper shakers.

This site is divided into several sections devoted to the the fabulous KOOL penguin, his history, collectibles, and media campaigns, as well as the whole controversy of using cartoon characters to pitch the evil weed.


THE HISTORY

While the primary purpose of this page is to showcase Willie the KOOL penguin collectibles, the origin and history of our little friend is of interest as well.  A good bit of research remains to be done, but it is safe to say that the KOOL penguin's longevity far exceeded that of the more infamous "Joe-come-lately."  For those with an interest in Willie's origin and transformation over the years, I have provided a KOOL Penguin History page for your perusal.  You'll find lots of nice images there too.



THE COLLECTIBLES

Sojourners at flea markets and antique shops regularly encounter the little plastic "Willie" and "Millie" salt and pepper shakers -- although perhaps not in rookery numbers.  They are by far the most common KOOL penguin collectibles.  However, there are a great many others, more than you would ever imagine.  The careful flea market shopper will also find "Willie" in other configurations, including cigarette lighters, counter-top displays, and posters, even an electric clock.  I invite you to visit the separate collectibles page for as complete a survey of these charming items as you are likely to find anywhere on Earth.

If you are a KOOL penguin collector with items to sell or trade, please take a look at my wanted and for trade page.  You may also be interested in the questionable items page.


THE POSTERS

There were several KOOL penguin posters, both large and small.  The example shown here is on stiff cardboard and is of the size that might have been displayed on a bus or subway car.  Willie posters can also be found on slick paper as well as in billboard size.  See the separate collectibles page for examples.


THE TIN SIGNS

There were also a number of tin signs, large and small, and in different configurations.  Some of them have holes in the four corners through which nails or screws could be used to affix them to a flat surface or door jam.  The one shown here measures 12" by 3½".  See the separate collectibles page for other examples.


MEDIA ADVERTISING

Magazine advertising featuring the KOOL penguin began appearing in the early '30s and continued at least until the late '50s.  The picture at left, from a 1935 magazine, depicts everyone's favorite outdoor activity--surfing and smoking.  By 1956, Willie had become more "cartoonish" and KOOL cigarettes had acquired a filter.

Other examples of magazine advertising may be found on the KOOL Penguin History page as well as on the separate collectibles page.


Willie the penguin was also featured in large in-store displays.  Seen here is a really nice one in the Paradise Pharmacy (Texas?), as it appeared circa the mid-1950s.

One of the most interesting advertising areas was the flip side of the cigarette pack, itself.  There, under the heading "Willie the Penguin Says," our feathered friend waxes poetic, dispensing such advice as: "Even if you cough like crazy, KOOLS still taste fresh as a daisy."


Here are a few examples of penguin poetic prowess.  There were many, many of these odd little poems.  You may go to the separate poetry page for additional examples.


THE MULTIMEDIA PAGE
Those of you who are as old as I am will remember a time when TV commercials for KOOL cigarettes featured an animated version of our little friend.  Assuming your computer supports the playing of mpeg-1 movie files, the MultiMedia Page will usher you back to that time.


THE CONTROVERSY

Now, if you want to talk about blatant advertising designed to introduce young children to the evils of the weed, consider this.  During the period April 1951 to April 1952, Standard Publications, had the distinction of publishing a comic book featuring our guy Willie.

Not to be confused with "Chilly Willy," the Brown and Williamson tobacco company actually held the copyright to this comic character.  For more on this byway, you may visit the separate Willie the Penguin comic book page.

The recent flap over "Joe Camel" may have the secondary effect of spurring new interest in our guy "Willie."   Indeed, in 1991, Brown and Williamson (U.S. subsidiary of transnational giant BAT Industries) tested an ad campaign based on a modernized version of the old KOOL penguin.  The "new" penguin has buzz-cut hair, day-glo sneakers, sunglasses, and is very conscious of being "cool."  Brown and Williamson's announcement of the test campaign was written in the voice of the penguin, who explains:

My older cousin, Willie the Penguin, represented Kool for three decades.  Let's face it, he's gotten on in years. That, and the fact that I'm unique, colorful, good-looking - and very modest.

The complete article from which I gleaned this information (together with a larger picture of the tough little guy) may be found on the "New Kool Penguin" page.  Does anyone out there know more about this?  Who can send me additional pictures or examples of any associated merchandise?


We find another image of the new KOOL penguin in an editorial cartoon, by Gary Brookins of the Richmond Times Dispatch, depicting the poor little guy as having joined the ranks of the unemployed.  It is my understanding that the new KOOL penguin campaign was test marketed in the Richmond area, so it makes sense that the local paper would be aware of it.


HELP!

If you are a retired employee of Brown and Williamson or the Batten, Barton, Durstine, and Osborn advertising agency (or anyone else for that matter), and have information or memorabilia relating to the KOOL penguin ad campaign, please contact me.  Your assistance in my research will be greatly appreciated.  I am particularly looking for old issues of the B&W employee magazine entitled "The Penguin."

I am always interested in buying or trading for those KOOL penguin items that are not already securely nestled under my wing.  Indeed, I invite you to visit my special wanted and for trade page.

And if you leave this page without looking at the separate collectibles page you will miss the bulk of the information and images included at this site.

Click here for your favorite eBay items

I am often asked "Where can I buy a set of Willie and Millie shakers?" or some other KOOL collectible.  The answer is -- the eBay auctions!  Click the eBay icon and become a registered member today.  Yes, it's free, but please don't bid against "Otto."  Hey folks, that's me!

Few among you is more averse to smoking than I.  Still, it is possible to be enchanted by Willie the Penguin despite the menace of his message.   Such is the power of advertising.

Please feel free to e-mail me with your comments.


If you would like to support this page and save yourself some money in the process, please consider shopping for your books, CDs, and videos from Amazon.com.


Just click one of these icons and bookmark or make a favorite of the page it takes you to.  Thereafter, your purchases from Amazon will produce a small credit to yours truly.  The eBay icon takes you to a list of items that my alter ego, Otto, is offering at auction this week.

Donations Are Welcome   If you are one of those rare angels who would like to make a modest donation to support my efforts, you may do so by clicking the Pay Pal "Donate" image and filling in the pertinent information that will appear on the next screen.  It's fast and easy and your surprising generosity will be greatly appreciated.

MORE?   Many other areas of the "Popular Culture Excavation Site" await you.  Full descriptions are on the main menu or go directly to the area of your choice by clicking one of these seductive little images.

The Katzenjammer KidsWillie the KOOL penguinMistinguettCarl "Duck Man" BarksSvend AsmussenTim "Kingfish" MooreWestern SwingHazel CourtRhythm and Blues RevuesEuropean Jazz and Close Harmony Vocal GroupsThe Pie Girl DinnerSally RandWLAC Radio: Nashville

Who are these guys?  Just place your cursor on each image to get a clue.

Return to the main menu.


On May 18, 2002, the 5th anniversary of the creation of the main site, hosting of this page was transferred from Yahoo/GeoCities to an independent server.  You are the most recent of the #!/usr/local/bin/perl5 use GD; alarm(600); # cgi-bin access counter program # Version 4.0.7 # # Copyright (C) 1995 George Burgyan # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # A full copy of the GNU General Public License can be retrieved from # http://www.webtools.org/counter/copying.html # # gburgyan@webtools.org # # George Burgyan # 1380 Dill Road # South Euclid, OH 44121 # # For more information look at http://www.webtools.org/counter/ ######################################################################## # # CHANGE THESE TO SUIT YOUR SITE # # The default language option (english, french, swedish) $default_lang = "english"; # The name of the file to use. You should probably give this an absolute path $FileName = "$ENV{'DOCUMENT_ROOT'}/counter/access_count"; # Replace with a list of regular expression IP addresses that we # are supposed to ignore. If you don't know what this means, just use # "\." instead of periods. Comment out entirely to ignore nothing. #@IgnoreIP = ("199\.18\.203\..*", # "199\.18\.159\.1", # ); # Aliases: Set this up so that diffent pages will all yield the same # count. For instance, if you have a link like "index.html -> home.html" # set it up like ("/index.html", "/home.html"). Make sure you give a full # path to it. This will treat "/index.html" as if it were "/home.html". %Aliases = ("/fakename.html", "/realname.html", "/index.html", "/home.html", ); # AUTOMATICALLY SET BY INSTALL!! Modify only if necessary!!! # # BaseName: set to whatever you have counter installed as. This is # used to derive the arguments. No not touch the next comment. ### AUTOMAGIC ### $BaseName = "counter"; # counter or counterbanner or counterfiglet # # Outputs the number of times a specific page has been accessed. # The output depends on which page 'called' it, and what the program # is named: # # The counter can "take arguments" via its name. That is, if you tack # -arg to the end of the program name, -arg is taken to be an argument. # For example, if you call the counter 'counter-ord', '-ord' is considered # an argument, and an ordinal count (1st, 2nd, 3rd, ...) will be printed # instead of (1, 2, 3, ...). Note that counterord does the same thing as # counter-ord for backward compatibility. # # Currently recognized arguments: # # -f=font sets "font" to be the font for figlet # -lang=lang sets the language used to ordinalize to "lang" # -nc no count; don't to write the incremented count back to the file # -nl no link; don't automatically generate a link # -nd no display; don't display anything, just count # -ord make an ordinal count instead of regular # -doc=document override the DOCUMENT_URI environment variable # # Example: counterfiglet-ord-f=bigfont-nc # # This will cause the counter to call figlet as the output routine, printing # in a big font an ordinal count, without updating the access count file. # Note that the order of arguments is irrelevant so long as you spell the # file name correctly. It is generally assumed that the ability to take # different arguments/use different output routines is done with symlinks: # i.e. ln -s counter counterfiglet-ord-f=bigfont-nc # # More complete documentation can be found at # http://www.webtools.org/counter/ # ######################################################################## # # Thing that shouldn't really need changing, but are configurable anyway. # # Maximum number of times to try to lock the file. # Each try is .1 second. Try for 1 second. $MaxTries = 10; # Set this to point to something, or comment it out, and it # won't be a link at all. # $Link = "http://www.webtools.org/counter/"; # Whether or not to use locking. If perl complains that flock is not # defined, change this to 0. Not *really* necessary because we check # to make sure it works properly. $UseLocking = 0; # What version of the counter file format are we using? $FileVersion = "02.000"; # Common names of the counter to install... @CommonExtensions = ("-ord", # Ordinam "figlet", # Figlet'ed "figlet-ord",# Ordinal figlet "banner", # Bannered "banner-ord",# Ordinal banner ); # ######################################################################### # # Misc documents to refer people to in case of errors. # $CreateFile = "[Error Creating Counter File -- Click for more info]"; $AccessRights = "[Error Opening Counter File -- Click for more info]"; $TimeoutLock = "[Timeout locking counter file]"; $BadVersion = "[Version access_count newer than this program. Please upgrade.]"; ######################################################################### # # The actual program! ### Stage 1 ### ### Parse the arguments... (just ignore this part) # Get arguments from program name. Argh...what a horrible way to do it! $prog = $0; $prog =~ s/(\.cgi|\.pl)//; #strip .cgi|.pl name extension $prog =~ s!^(.*/)!!; # separate program name $prog =~ s/\\(.)/sprintf("%%%02x", ord($1))/ge; # quote \c to %xx ($printer, @args) = split(/-/, $prog); # args are separated by dashes $printer =~ s/%(..)/pack("c", hex($1))/ge; # unquote printer function name $printer =~ s/$BaseName/counter/; # Make it cannonical. # This gets path info, which is only applicable if you are using our # ssis script (see above). This makes counter/ord the same as counter-ord push(@args, split("/", $ENV{"PATH_INFO"})) if $ENV{"PATH_INFO"}; # put them in assoc array %arg foreach (@args) # means do this for each element in the array { s/%(..)/pack("c", hex($1))/ge; # unquote %xx /^([^=]*)=?(.*)$/; # extract "=" part, if any $arg{$1} = $2 ? $2 : 1; } if ($ARGV[0] eq '-install') { &CheckPerl; &SetBaseName; &MakeCommon(0); exit(0); } if ($ARGV[0] eq '-installforce') { &CheckPerl; &SetBaseName; &MakeCommon(1); exit(0); } if ($ARGV[0] eq '-unlock') { open(FILE,"$FileName"); &UnlockFile(FILE); exit(0); } undef $Link if $arg{'nl'}; # make link? ### Stage 2 ### ### Print out the header # Print out the header print "Content-type: text/html\n\n"; #print "Debug 1: $ConfName
Debug 2: $FileName"; ### Stage 3 ### ### Open the access_count file for read-write taking all the precautions # Make sure the file exists: if (!(-f $FileName)) { if (!open (COUNT,">$FileName")) { # Can't create the file print $CreateFile; exit 1; } else { # We got the file, print out the version number print COUNT "$FileVersion\n"; $version = 2; } } else { if (!((-r $FileName) && (-w $FileName))) { # Make sure that we can in fact read and write to the file in # question. If not, direct them to the FAQ. print $AccessRights; exit 1; } if (!open (COUNT,"+<$FileName")) { # Now make sure it *really* opens print $AccessRights; # ...just in case... exit 1; } # Try to read in a version number $version = ; if (!($version =~ /^\d+.\d+$/)) { # No version number, assume version 1 and reset the file. $version = 1; seek(COUNT,0,0); } } # This is for the future: the access_count file will have a version number. if ($version > 2) { print $BadVersion; exit 1; } ### Stage 4 ### ### Attempt to lock the file $lockerror = &LockFile(COUNT); # You would figure that $MaxTries would equal 0 if it didn't work. The # post-decrement takes it to -1 when the loop finally exits. if ($lockerror) { print $TimeoutLock; exit(0); } ### Stage 5 ### ### Check if we need to update the file to a newer version if ($version < 2) { &UpdateVersion1; } ### Stage 6 ### ### Convert the information the server gave us into the document ### identifier. # Make sure perl doesn't spit out warnings... if (defined $ENV{'DOCUMENT_URI'}) { $doc_uri = $ENV{'DOCUMENT_URI'}; } else { $doc_uri = ""; } # Campatibility: Version 2 files have the server name in front if and # only if it doesn't have a "~" in it. $old_uri = $doc_uri; # Add the server name in front to support multi-homed hosts if and only if # it doesn't have a "~" in it. (usernames are global in most multi-homed # settings if (defined $ENV{'SERVER_NAME'} && !($doc_uri =~ /~/)) { $doc_uri = $ENV{'SERVER_NAME'} . "/" . $doc_uri; } if (defined $arg{'doc'}) { $doc_uri = $arg{'doc'}; } $doc_uri = $Aliases{$doc_uri} if defined $Aliases{$doc_uri}; ### Stage 7 ### ### Find the relevant place in the file $location = tell COUNT; while ($line = ) { # Read the file line-by-line. if (($uri,$accesses) = ($line =~ /^'(\S*)' (\d\d\d\d\d\d\d\d\d\d)$/)) { # An old line if ($uri eq $old_uri) { &ConvertDocV1($doc_uri,$old_uri,$accesses,$location); last; } } elsif (($uri,$accesses,$flags) = ($line =~ /^'(\S*)' (\d\d\d\d\d\d\d\d\d\d) (\w\w\w\w)$/)) { # A new line if ($uri eq $doc_uri) { $flags = hex($flags); last; } } last if ($uri eq $doc_uri); $location = tell COUNT; #reset the fields $accesses = 0; $flags = 0; } ### Stage 8 ### ### Update the access count of the file $accesses += 1; # *NOT* '++' because we don't want '++'s magic ### Stage 9 ### ### Figure out what to print out # If we have to ordinalize, do it now. if (defined $arg{'ord'}) { if (defined $arg{'lang'}) { $ord = eval("&ordinalize_$arg{lang}($accesses)"); } else { $ord = &ordinalize($accesses); } } else { $ord = ""; } $to_print = $accesses . $ord; # Give it to the printer function to actually produce the output from the # ascii text that we have (to_print) ($count, $nLink) = eval("&output_$printer('$to_print')"); # If the above line gave us an error, default to just the text. if ($@) { ($count, $nLink) = &output_counter($to_print); } ### Stage 10 ### ### Now we actually tell the browser what the count is. if (! $arg{"nd"} ) { # If we print anything # Print out a link to something informative (if we were requested to) $script_name = $ENV{'SCRIPT_NAME'}; print "" if $nLink; if ($script_name =~ /cgi-bin\/count(\w+)/) { $img_dir = $1; } if ($img_dir ne "er") { &give_graphic } else { print $count; print "" if $nLink; } } sub give_graphic { @img_count = split(//,$count); foreach (@img_count) { print ""; }; } sub comment1 { # create a new image print "Content-type: image/gif\n\n"; $im = new GD::Image(100,100); # allocate some colors $white = $im->colorAllocate(255,255,255); $black = $im->colorAllocate(0,0,0); $red = $im->colorAllocate(255,0,0); $blue = $im->colorAllocate(0,0,255); # make the background transparent and interlaced $im->transparent($white); $im->interlaced('true'); # Put a black frame around the picture $im->rectangle(0,0,99,99,$black); # Draw a blue oval $im->arc(50,50,95,75,0,360,$blue); # And fill it with red $im->fill(50,50,$red); # Convert the image to GIF and print it on standard output print $im->gif; } ### Stage 11 ### ### Check if we are supposed to update the count in the file. (ie. we're ### not ignoring the host that just accessed us) # Make sure we are not ignoring the host: $ignore = 0; $ignore = grep($ENV{"REMOTE_ADDR"} =~ /$_/, @IgnoreIP) if defined ($ENV{"REMOTE_ADDR"}); $ignore = $ignore || $arg{"nc"}; ### Stage 12 ### ### Actually write the updated information back to the file if (!$ignore) # If we aren't ignoring this access { # Now update the counter file seek(COUNT, $location, 0); $longaccesses = sprintf("%010.10d", $accesses); $hexflags = sprintf("%04.4x", $flags); print COUNT "'$doc_uri' $longaccesses $hexflags\n"; } &UnlockFile(COUNT); close COUNT; ####################################################################### # # Support functions # # translate_output # # Quote any special characters with HTML quoting. sub translate_output { local($string) = @_; $_ = $string; s/è/è/g; return $_; } sub LockFile { local(*FILE) = @_; local($TrysLeft) = $MaxTries; if ($UseLocking) { # Try to get a lock on the file while ($TrysLeft--) { # Try to use locking, if it doesn't use locking, the eval would # die. Catch that, and don't use locking. # Try to grab the lock with a non-blocking (4) exclusive (2) lock. # (4 | 2 = 6) $lockresult = eval("flock(COUNT,6)"); if ($@) { $UseLocking = 0; last; } if (!$lockresult) { select(undef,undef,undef,0.1); # Wait for 1/10 sec. } else { last; # We have gotten the lock. } } } if ($TrysLeft >= 0) { # Success! return 0; } else { return -1; } } sub UnlockFile { local(*FILE) = @_; if ($UseLocking) { flock(FILE,8); # Unlock the file. } } #################################################################### # # Installation helpers # # SetBaseName # # Change the counter program itself to set the basename sub SetBaseName { local($name) = $0; $name =~ s/^.*\/([^\/]+)$/$1/; # Strip off any of the path if ($name eq $BaseName) { # The way we're set up now!!! return; # Don't need to change a thing. } if (!open(COUNTERFILE, "+<$0")) { print "Can't modify program. Set \$BaseName manually.\n"; return; } print "Configuring \$BaseName variable...\n"; local($oldsep) = $/; undef($/); local($program) = ; # The next line does all the magic. $program =~ s/\#\#\# AUTOMAGIC \#\#\#\n\$BaseName = \"[^\"]+\";\n/\#\#\# AUTOMAGIC \#\#\#\n\$BaseName = \"$name\";\n/; seek(COUNTERFILE,0,0) || return; truncate(COUNTERFILE,0); print COUNTERFILE $program; close COUNTERFILE; } # CheckPerl # # Make sure that the "#! /[path]/perl" points to something real... sub CheckPerl { if (!open(COUNTERFILE, "<$0")) { print "Can't check to make sure Perl is in the right place.\n"; return; } print "Checking to make sure Perl is found properly...\n"; $firstline = ; ($command) = ($firstline =~ /^\#! *([^\s]+) *$/); close(COUNTERFILE); if (! -x $command) { print "The location of Perl is misconfigured. Please edit the\n"; print "first line of this program to point to the locally installed\n"; print "copy of perl.\n\n"; print "Currently, it is configured to be \"$command\", however,\n"; print "that file either does not exist or is not a program.\n\n"; print "Some common locations for Perl are:\n"; print " /usr/bin/perl\n"; print " /usr/local/bin/perl\n"; print " /bin/perl\n"; print " /opt/gnu/bin/perl\n\n"; exit; } } # MakeCommon # # Make some common links to the counter sub MakeCommon { local($force) = @_; local($ext); print "Installing the counter...\n"; print " ...making counter executable\n"; chmod(0755,$0); local($path, $name, $cgi); $name = $0; if ($name =~ /^(.*\/)([^\/]+)$/) { $path = $1; $name = $2; } if ($name =~ /^(.*)(\.cgi)$/) { $name = $1, $cgi = $2; } foreach $ext (@CommonExtensions) { print " ...making link from $path$name$cgi to $path$name$ext$cgi\n"; if (!&MakeLink("$path$name$cgi","$path$name$ext$cgi",$force)) { # An error occured while making the link. :-( print " *** An error occured while making the link.\n"; } } if ($symlink_exists == 0 && $link_exists == 0) { print "* NOTE * Your system does not support symbolic or hard links,\n"; print " copies made instead. If you modify the counter, you must\n"; print " run counter -install again to recopy it to the other files.\n"; } print "...done!\n"; } # MakeLink # # Actually create the link. sub MakeLink { local($oldname,$newname,$force) = @_; # Check to see if we can make symbolic links instead of hard links if (!defined $symlink_exists) { $symlink_exists = (eval 'symlink("","");', $@ eq ''); } # Check to see if we can make a link if we can't make a symlink if (!symlink_exists) { $link_exists = (eval 'link("","");', $2 eq ''); } if ($force) { # Check to see if the file exists if (-e $newname) { if (!unlink ($newname)) { return 0; } } } if ($symlink_exists) { return symlink($oldname, $newname); } elsif ($link_exists) { return link($oldname, $newname); } else { # Copy it the old-fashioned way... *sigh* open(OLDFILE, $oldname) || die "Can't open $oldname for copy"; open(NEWFILE, ">$newname") || die "Can't open $newname for write"; while() { print NEWFILE $_; } close(NEWFILE); close(OLDFILE); } } #################################################################### # # Ordinalizing functions # # ordinalize # # Call the appropriate ordinalize function for the default language sub ordinalize { local($count) = @_; if (defined $arg{'lang'}) { return eval("&ordinalize_$arg{lang}($count)"); } else { return eval("&ordinalize_$default_lang($count)"); } } # ordinalize_english # # Figure out what suffix (st, nd, rd, th) a number would have in ordinal # form and return that extension. sub ordinalize_english { local($count) = @_; local($last, $last2); $last2 = $count % 100; $last = $count % 10; if ($last2 < 10 || $last2 > 13) { return "st" if $last == 1; return "nd" if $last == 2; return "rd" if $last == 3; } return "th"; # Catch "eleventh, twelveth, thirteenth" etc. } # ordinalize_french # # Trivial... Return the extension for french. The only exception is 1. # Thank you Chris Polewczuk sub ordinalize_french { local ($count) = @_; if ($count == 1) { return "'ière"; } else { return "ième"; } } # ordinalize_swedish # # A function to ordinalize in Swedish. Thanks go to Johan Linde # for the code! sub ordinalize_swedish { local($count) = @_; local($last, $last2); $last2 = $count % 100; $last = $count % 10; if ($last2 < 10 || $last2 > 12) { return ":a" if ($last == 1 || $last == 2); } return ":e"; } ######################################################################## # # Output functions # # The following are the routines that actually convert the number # of accesses into something that we print out. # # The name of each function is "output_" followed by the program's name. # For instance, is the program is called "counter" then "output_counter" # will be called; a program called "counterbanner" will call # "output_counterbanner" to get the output. # # If the function is not defined, then "output_counter" will be called. # # output_counter # # The simplest function: just returns the number of accesses and the link. sub output_counter { local($count) = @_; return &translate_output($count), $Link; # we return the count and the link } # output_counterord # # Return the number of accesses as an ordinal number. (ie. 1st, 2nd, 3rd, 4th) sub output_counterord { local($count) = @_; return &translate_output($count . &ordinalize($count)), $Link; } # output_counterbanner # # A somewhat silly one that uses the "banner" command to print out the # count. :) You might need to change the path to make it work. sub output_counterbanner { local($count) = @_; $banner = `banner $count`; return "

$banner
"; # return no link here (it would be annoying) } # output_counterfiglet # # An even sillier one than counterbanner. :) sub output_counterfiglet { local($count) = @_; $fig = "echo $count | /usr/games/figlet"; # setup command line $fig .= " -f $arg{'f'}" if $arg{"f"}; # use a different font? $fig = `$fig`; $fig =~ s!&!&!g; $fig =~ s!
" . $fig . "
"; # note no link here, either } ######################################################################### # # Conversion functions # # UpdateVersion # # Convert a version 1file into a version 2 file. sub UpdateVersion1 { local ($contents,$dummy); local ($oldsep) = $/; $/ = ""; seek(COUNT,0,0); # Go to the beginning of the file $contents = ; seek(COUNT,0,0); print COUNT "$FileVersion\n"; print COUNT $contents; seek(COUNT,0,0); $/ = $oldsep; $dummy = ; # Skip the new line } # ConvertDocV1 # # Convert the a version 1 line into a version 2 line sub ConvertDocV1 { local ($doc_uri,$old_uri,$accesses,$location) = @_; local ($contents,$dummy,$oldsep); $oldsep = $/; seek (COUNT,$location,0); # Skip the line in question $dummy = ; $/ = ""; # Read in the whole file $contents = ; seek (COUNT,$location,0); local ($longaccesses,$hexflags); $longaccesses = sprintf("%010.10d", $accesses); $hexflags = sprintf("%04.4x", $flags); # Print out the new stuff print COUNT "'$doc_uri' $longaccesses $hexflags\n"; print COUNT $contents; $/ = $oldsep; } cognoscenti who have ventured to this page since that date.


This page created and maintained by Jim Lowe
First appearance: May 18, 1997
Last updated: June 5, 2002

© 1997 to 2002 by James R. Lowe, who reserves all rights to the content of this page not successfully claimed by others.  "Willie" and "Millie" the KOOL penguins might be copyright characters (if they ever were, and it hasn't expired) of Brown and Williamson.  In any case, their appearance on this page is in the context of a review or critical commentary and is within the "fair use" provisions of the copyright act.