Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83 (MC840302); site mcvax.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!godot!harvard!seismo!mcvax!play From: play@mcvax.UUCP (funhouse) Newsgroups: net.sources Subject: Hack sources (part 1 of 15) Message-ID: <6243@mcvax.UUCP> Date: Mon, 17-Dec-84 19:26:34 EST Article-I.D.: mcvax.6243 Posted: Mon Dec 17 19:26:34 1984 Date-Received: Wed, 19-Dec-84 00:46:31 EST Organization: CWI, Amsterdam Lines: 790 # This is part 1 (of 15) of the Hack sources. Send complaints to # mcvax!play . # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # Bugs Makefile Original_READ_ME Porting READ_ME alloc.c config.h data date.h echo x - Bugs cat > "Bugs" << '//E*O*F Bugs//' - the locking system is ridiculous - the access of record should be locked - record should be encrypted - the level files and the save file should be encrypted and stored in the users directory - for vaxen: mklev should be incorporated in hack //E*O*F Bugs// echo x - Makefile cat > "Makefile" << '//E*O*F Makefile//' # Hack or Quest Makefile. # on some systems the termcap library is in -ltermcap TERMLIB = -ltermlib # make hack GAME = hack CAPGAME = HACK GAMEDIR = ../tmp CFLAGS = -O HACKCSRC = hack.Decl.c\ hack.apply.c hack.bones.c hack.c hack.cmdlist.c hack.do.c\ hack.do_name.c hack.do_wear.c hack.dog.c hack.eat.c hack.end.c\ hack.engrave.c hack.fight.c hack.invent.c hack.ioctl.c\ hack.lev.c hack.main.c hack.makemon.c\ hack.mkobj.c hack.mhitu.c\ hack.mon.c hack.monst.c hack.o_init.c hack.objnam.c\ hack.options.c\ hack.pri.c hack.read.c hack.rip.c hack.rumors.c\ hack.save.c\ hack.search.c hack.shk.c hack.stat.c hack.steal.c\ hack.termcap.c hack.timeout.c hack.topl.c\ hack.track.c hack.trap.c hack.tty.c hack.u_init.c hack.vault.c\ hack.whatis.c hack.wield.c hack.worm.c hack.worn.c hack.zap.c\ hack.version.c rnd.c alloc.c CSOURCES = $(HACKCSRC) mklev.c mklv.shk.c mklv.shknam.c mklv.makemaz.c\ makedefs.c HSOURCES = savelev.h\ mklev.h hack.h hack.mfndpos.h config.h\ def.edog.h def.eshk.h def.func_tab.h def.gen.h def.objclass.h\ def.monst.h def.obj.h def.permonst.h def.trap.h def.wseg.h\ def.objects.h SOURCES = $(CSOURCES) $(HSOURCES) AUX = data help hh rumors hack.6 hack.sh HOBJ = hack.Decl.o hack.apply.o hack.bones.o hack.o hack.cmdlist.o hack.do.o\ hack.do_name.o hack.do_wear.o hack.dog.o hack.eat.o hack.end.o\ hack.engrave.o hack.fight.o hack.invent.o hack.ioctl.o\ hack.lev.o hack.main.o hack.makemon.o\ hack.mkobj.o hack.mhitu.o hack.mon.o\ hack.monst.o hack.o_init.o hack.objnam.o hack.options.o hack.pri.o\ hack.read.o hack.rip.o\ hack.rumors.o hack.save.o\ hack.search.o\ hack.shk.o hack.stat.o hack.steal.o hack.termcap.o\ hack.timeout.o hack.topl.o\ hack.track.o hack.trap.o\ hack.tty.o hack.u_init.o hack.vault.o hack.whatis.o hack.wield.o\ hack.worm.o hack.worn.o hack.zap.o\ hack.version.o GOBJ = rnd.o alloc.o all: $(GAME) mklev @echo "Made Hack." $(GAME): $(HOBJ) $(GOBJ) Makefile @echo "Loading ..." @ld -X -o $(GAME) /lib/crt0.o $(GOBJ) $(HOBJ) $(TERMLIB) -lc makedefs: makedefs.c cc -o makedefs makedefs.c hack.onames.h: makedefs def.objects.h makedefs > hack.onames.h mklv.mkobj.o: mklev.h hack.onames.h hack.mkobj.c rm -f mklv.mkobj.c ln hack.mkobj.c mklv.mkobj.c cc -c $(CFLAGS) -DMKLEV mklv.mkobj.c rm -f mklv.mkobj.c mklv.makemon.o: mklev.h hack.makemon.c rm -f mklv.makemon.c ln hack.makemon.c mklv.makemon.c cc -c $(CFLAGS) -DMKLEV mklv.makemon.c rm -f mklv.makemon.c mklv.o_init.o: hack.o_init.c def.objects.h hack.onames.h rm -f mklv.o_init.c ln hack.o_init.c mklv.o_init.c cc -c $(CFLAGS) -DMKLEV mklv.o_init.c rm -f mklv.o_init.c mklev.o: cc -c $(CFLAGS) -DMKLEV mklev.c MKLOBJ = mklev.o hack.monst.o mklv.o_init.o mklv.mkobj.o mklv.shk.o\ mklv.shknam.o mklv.makemon.o mklv.makemaz.o $(GOBJ) mklev: $(MKLOBJ) cc -o mklev $(MKLOBJ) lint: lint_h lint_m @echo "Lint done." lint_h: # lint cannot have -p here because (i) capitals are meaningful: # [Ww]izard, (ii) identifiers may coincide in the first six places: # doweararm() versus dowearring(). # _flsbuf comes from , a bug in the system libraries. lint -axbh -DLINT $(HACKCSRC) | sed '/_flsbuf/d' > olint_h cat olint_h | sed '/never used/d;/warning/d' lint_m: lint -axbh -DLINT -DMKLEV mklev.c hack.makemon.c hack.monst.c\ hack.o_init.c hack.mkobj.c mklv.shk.c mklv.makemaz.c alloc.c\ rnd.c print: print *.h Makefile $(AUX) print mklev.c mklev.*.c rnd.c alloc.c hack.c print hack.Decl.c Hack.magic.C hack.[a-m]*.c print hack.[n-z]*.c print show.c makedefs.c diff: @- for i in $(SOURCES) $(AUX) ; do \ echo ; echo diff $D/$$i $$i ; \ diff $D/$$i $$i ; done distribution: Makefile @- for i in READ_ME $(SOURCES) $(AUX) Makefile date.h hack.onames.h\ ; do \ cmp -s $$i $D/$$i || \ ( echo cp $$i $D ; cp $$i $D ) ; done # the distribution directory also contains the empty files # perm and record, and the informative files Porting and Bugs. install: rm -f /usr/games/$(CAPGAME) cp $(GAME) /usr/games/$(CAPGAME) # chmod 0710 /usr/games/$(CAPGAME) chmod 04711 /usr/games/$(CAPGAME) rm -f $(GAMEDIR)/mklev cp mklev $(GAMEDIR)/mklev # chmod 0750 $(GAMEDIR)/mklev chmod 0751 $(GAMEDIR)/mklev rm -f $(GAMEDIR)/bones* depend: # For the moment we are lazy and disregard /usr/include files because # the sources contain them conditionally. Perhaps we should use cpp. # -e 's,<\(.*\)>,"/usr/include/\1",' \ # for i in ${CSOURCES}; do \ ( /bin/grep '^#[ ]*include' $$i | sed -n \ -e '/<.*>/d' \ -e 's/[^"]*"\([^"]*\)".*/\1/' \ -e H -e '$$g' -e '$$s/\n/ /g' \ -e '$$s/.*/'$$i': &/' -e '$$s/\.c:/.o:/p' \ >> makedep); done for i in ${HSOURCES}; do \ ( /bin/grep '^#[ ]*include' $$i | sed -n \ -e '/<.*>/d' \ -e 's/[^"]*"\([^"]*\)".*/\1/' \ -e H -e '$$g' -e '$$s/\n/ /g' \ -e '$$s/.*/'$$i': &\ touch '$$i/p \ >> makedep); done @echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep @echo '$$r makedep' >>eddep @echo 'w' >>eddep @cp Makefile Makefile.bak ed - Makefile < eddep rm eddep makedep @echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile @echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile @echo '# see make depend above' >> Makefile - diff Makefile Makefile.bak @rm -f Makefile.bak # DO NOT DELETE THIS LINE hack.Decl.o: hack.h hack.apply.o: hack.h def.edog.h hack.bones.o: hack.h hack.o: hack.h def.trap.h hack.cmdlist.o: config.h def.objclass.h def.func_tab.h hack.dog.o: hack.h hack.mfndpos.h def.edog.h hack.eat.o: hack.h hack.engrave.o: hack.h hack.fight.o: hack.h hack.invent.o: hack.h def.wseg.h hack.main.o: hack.h hack.makemon.o: mklev.h hack.h hack.mkobj.o: mklev.h hack.h hack.onames.h hack.mhitu.o: hack.h hack.mon.o: hack.h hack.mfndpos.h hack.monst.o: mklev.h def.eshk.h hack.o_init.o: config.h def.objects.h hack.onames.h hack.objnam.o: hack.h hack.options.o: config.h hack.h hack.pri.o: hack.h def.wseg.h hack.read.o: hack.h hack.rumors.o: config.h hack.search.o: hack.h def.trap.h hack.shk.o: hack.h hack.mfndpos.h def.eshk.h hack.steal.o: hack.h hack.termcap.o: config.h hack.timeout.o: hack.h hack.track.o: hack.h hack.trap.o: hack.h def.trap.h hack.vault.o: hack.h hack.whatis.o: hack.h hack.wield.o: hack.h hack.worm.o: hack.h def.wseg.h hack.worn.o: hack.h hack.zap.o: hack.h hack.version.o: date.h mklev.o: mklev.h def.trap.h savelev.h mklv.shk.o: mklev.h def.eshk.h mklv.shknam.o: mklev.h mklv.makemaz.o: mklev.h mklev.h: config.h def.objclass.h def.monst.h def.gen.h def.obj.h def.permonst.h touch mklev.h hack.h: mklev.h hack.onames.h touch hack.h def.objects.h: def.objclass.h touch def.objects.h # DEPENDENCIES MUST END AT END OF FILE # IF YOU PUT STUFF HERE IT WILL GO AWAY # see make depend above //E*O*F Makefile// echo x - Original_READ_ME cat > "Original_READ_ME" << '//E*O*F Original_READ_ME//' This is export hack, my first semester programming project. To set it up for your system, you will have to do the following: 1: create a hack uid, to own the top ten list, etc. 2: create a hack directory "/usr/lib/game/hack" is the default. 2.5: make the directory 700 mode. /* sav files go in there...*/ 3: modify hack.main.c to use the new directory. 4: modify hack.main.c so it uses the new hack gid. Gid accounts can go into magic mode without the password, can get cores with ^G, etc. (make sure gid isn't checked anywhere else...) 5: recompile hack. 6: put it in games after making it set-uid hack. 8: fix the bugs I undobtedly left in it. 9: tell me what you think of it. Hack uses the UCB file /etc/termcap to get your terminal escape codes. If you don't use it, you will have to make extensive changes to hack.pri.c If you find any bugs (That you think I don't know about), or have any awesome new changes (Like a better save (One that works!)), or have ANY questions, write me Jay Fenlason 29 East St. Sudbury Mass. 01776 or call me at (617) 443-5036. Since I have both a modem and a teen-age sister, Good Luck. Hack is split (roughly) into several source files that do different things. I have tried to fit all the procedures having to do with a certain segment of the game into a single file, but the job is not the best in the world. The rough splits are: hack.c General random stuff and things I never got around to moving. hack.main.c main() and other random procedures, also the lock file stuff. hack.mon.c Monsters, moving, attacking, etc. hack.do.c drink, eat, read, wield, save, etc. hack.do1.c zap, wear, remove, etc... hack.pri.c stuff having to do with the screen, most of the terminal independant stuff is in here. hack.lev.c temp files and calling of mklev. Because of the peculiar restraints on our system, I make mklev (create a level) a separate procedure execd by hack when needed. The source for mklev is (Naturaly) mklev.c. You may want to put mklev back into hack. Good luck. Most of hack was written by me, with help from Kenny Woodland (KW) (general random things including the original BUZZ()) Mike Thome (MT) (The original chamelian) and Jon Payne (JP) (The original lock file kludge and the massive CURS()) This entire program would not have been possible without the SFSU Logo Workshop. I am eternally grateful to all of our students (Especially K.L.), without whom I would never have seen Rogue. I am especially grateful to Mike Clancy, without whose generous help I would never have gotten to play ROGUE. //E*O*F Original_READ_ME// echo x - Porting cat > "Porting" << '//E*O*F Porting//' Some remarks that may be useful when you try porting hack. This program has grown slowly but steadily for several years. Its original version was very buggy, and debugging soon became rewriting. The program still bears all the signs of this slow evolution: many similar problems are solved in dissimilar ways, which is often rather confusing. Also, the program is much less modular than it appears to be. Be very careful when you change a piece of code! - everything depends on everything. When we got the program one could not play for a quarter of an hour without getting a core dump. Now a core dump is observed once every other month (say, once in a thousand games). The source was written and is reasonably well tested out on a vax with BSD4.* . Older versions of the program run on a PDP11/45 with V7, but at present the program is much too large. As far as I can see, there are not many hidden assumptions about the host machine, but there might well be problems if one cannot cast a pointer into an integer or vice versa. It is assumed that any structure can be at the address of a long. The dialect of C used is rather rich: we use bitfields, structure assignments and functions returning structures. Porting to a M68000 with V7 took about one hour ( + compilation time) to get the program running, and two evenings to locate a strange bug in the shopkeeper movement, that turned out to be a bug in the local C-compiler. One hour of editing: Locate all identifier pairs that have the first 7 characters in common, and rename. [Note that case is important, and that some pairs of identifiers have 10 or more initial characters in common. Also note that some identifiers are generated by the program makedefs (such as CROSSBOW and CROSSBOW_BOLT or DEAD_GIANT_RAT and DEAD_GIANT_ANT or WORTHLESS_PIECE_OF_BLUE_GLASS and WORTHLESS_PIECE_OF_YELLOW_GLASS). If your C-compiler distinguishes 7 or more symbols then the work is annoying but doable. However, if you are the unlucky one with a compiler that only retains 6 symbols, then you probably should write a C-program compactifier that reads a C program and outputs an equivalent program but with all tags replaced by short ones (like T0, T1, ...). This is easy but not entirely trivial; e.g., references to external variables and routines should remain intact.] Two evenings of digging: It turned out that the C-compiler on this M68000 got confused when there were too many variables declared register char. [After register char x,y; x = 1; y = 2; the variable x would contain 0, i.e., for the assignment y = 2 a word-move was generated.] Right now this M68000 version seems to work flawlessly. (Note that I do not distribute a M68000 version; this porting work was done on a machine I no longer have access to.) //E*O*F Porting// echo x - READ_ME cat > "READ_ME" << '//E*O*F READ_ME//' Hack is a display oriented dungeons & dragons - like game. Both display and command structure resemble rogue. (For a game with the same structure but entirely different display - a real cave instead of dull rectangles - try Quest) Hack was originally written by Jay Fenlason (at lincolnsudbury: 29 East St., Sudbury Mass., 01776) with help from Kenny Woodland, Mike Thome and Jon Payne. Basically it was an implementation of Rogue, however, with 52+ instead of 26 monster types. The current version is more than twice as large (with such new features as the dog, the long worms, the shops, etc.) and almost entirely rewritten (only the display routines are the original ones - I must rewrite these too one day; especially when you are blind strange things still happen). Files for hack: hack The actual game mklev The program that constructs the dungeon record Top 100 list (just start with an empty file) news Tells about recent changes in hack, or bugs found ... (Just start with no news file.) data Auxiliary file used by hack to give you the names and sometimes some more information on the objects and monsters. help Introductory information (no doubt outdated). hh Compactified version of help. perm An empty file used for locking purposes. rumors Texts for fortune cookies. (Some of these contain information on the game, others are just plain stupid. Additional rumors are appreciated.) hack.sh A shell script. (We have hack.sh in /usr/games/hack and hack in /usr/games/HACK and all the other hack stuff in /usr/games/lib/hack/tmp - perhaps this will make the script clear. There is no need for you to use it.) READ_ME This file. Original_READ_ME Jay Fenlason's READ_ME System files used: /etc/termcap Used in conjunction with the environment variable $TERM. /bin/cat /usr/ucb/more /bin/sh Used when $SHELL is undefined. How to install hack: 0. Compile the sources. Perhaps you should first look at the file config.h and define BSD if you are on a BSDtype system, VAX if your C-compiler accepts struct initializations like PCC (and unlike the old V6 compiler on the PDP11/45), STUPID if your C-compiler chokes on complicated expressions; if your C compiler doesnt allow initialization of bit fields change Bitfield. When config.h looks reasonable, say 'make'. 1. If it didnt exist already, introduce a loginnname `play' . 2. The program hack resides in a directory so that it is executable for everybody and is suid play: ---s--s--x 1 play 132096 Aug 10 13:43 HACK Perhaps you wish to restrict playing to certain hours, or have games running under nice; in that case you might write a program play.c such that the program play is suid play and executable for everybody while all the games in /usr/games are readable or executable for play only; all the program play does is asking for the name of a game, checking that time-of-day and system load do not forbid playing, and then executing the game. Thus: -r-sr-sr-x 1 play 13312 May 24 12:52 play ---x------ 1 play 132096 Aug 10 13:43 HACK If you are worried about security you might let play do chroot("/usr/games") so that no player can get access to the rest of the system via shell escapes and the likes. 3. The rest of the stuff belonging to hack sits in a subdirectory hackdir (on our system /usr/games/lib/hack/tmp) with modes drwx------ 3 play 1024 Aug 9 09:03 hackdir Here all the temporary files will be created (with names like xlock.17 or user.5). 4. If you are not really short on file space, creating a subdirectory hackdir/save (modes again drwx------) will enable users to save their unfinished games. The program hack is called $ HACK [-d hackdir] [maxnrofplayers [pagingprogram]] (for playing) or $ HACK [-d hackdir] -s [listofusers | limit | all] (for seeing part of the scorelist). You will never want to call mklev, it is called from hack. The shell file hack (in this kit called hack.sh) takes care of calling HACK (in this kit called hack) with the right arguments. Send complaints, bug reports, suggestions for improvements to mcvax!aeb - in real life Andries Brouwer. //E*O*F READ_ME// echo x - alloc.c cat > "alloc.c" << '//E*O*F alloc.c//' #ifdef LINT /* a ridiculous definition, suppressing "possible pointer alignment problem" for (long *) malloc() "enlarg defined but never used" "ftell defined (in ) but never used" from lint */ #include long * alloc(n) unsigned n; { long dummy = ftell(stderr); if(n) dummy = 0; /* make sure arg is used */ return(&dummy); } #else extern char *malloc(); extern char *realloc(); long * alloc(lth) register unsigned lth; { register char *ptr; if(!(ptr = malloc(lth))) panic("Cannot get %d bytes", lth); return((long *) ptr); } long * enlarge(ptr,lth) register char *ptr; register unsigned lth; { register char *nptr; if(!(nptr = realloc(ptr,lth))) panic("Cannot reallocate %d bytes", lth); return((long *) nptr); } #endif LINT //E*O*F alloc.c// echo x - config.h cat > "config.h" << '//E*O*F config.h//' /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ #ifndef CONFIG /* make sure the compiler doesnt see the typedefs twice */ #define CONFIG #define VAX /* to get proper struct initialization */ #define BSD /* delete this line on System V */ /* #define STUPID */ /* avoid some complicated expressions if your C compiler chokes on them */ #define WIZARD "play" /* the person allowed to use the -w option */ #define NEWS "news" /* the file containing the latest hack news */ #define FMASK 0660 /* file creation mask */ #define OPTIONS /* do not delete the 'o' command */ #define SHELL /* do not delete the '!' command */ #define TRACK /* do not delete the tracking properties of monsters */ /* size of terminal screen is (ROWNO+2) by COLNO */ #define COLNO 80 #define ROWNO 22 /* * small signed integers (8 bits suffice) * typedef char schar; * will do when you have signed characters; otherwise use * typedef short int schar; */ typedef char schar; /* * small unsigned integers (8 bits suffice - but 7 bits do not) * - these are usually object types; be careful with inequalities! - * typedef unsigned char uchar; * will be satisfactory if you have an "unsigned char" type; otherwise use * typedef unsigned short int uchar; */ typedef unsigned char uchar; /* * small integers in the range 0 - 127, usually coordinates * although they are nonnegative they must not be declared unsigned * since otherwise comparisons with signed quantities are done incorrectly * (thus, in fact, you could make xchar equal to schar) */ typedef char xchar; typedef xchar boolean; /* 0 or 1 */ #define TRUE 1 #define FALSE 0 /* * Declaration of bitfields in various structs; if your C compiler * doesnt handle bitfields well, e.g., if it is unable to initialize * structs containing bitfields, then you might use * #define Bitfield(x,n) xchar x * since the bitfields used never have more than 7 bits. (Most have 1 bit.) */ #define Bitfield(x,n) unsigned x:n #endif CONFIG //E*O*F config.h// echo x - data cat > "data" << '//E*O*F data//' @ human (or you) - a wall | a wall + a door . the floor of a room # a corridor } water filled area < the staircase to the previous level > the staircase to the next level ^ a trap $ a pile, pot or chest of gold % a piece of food ! a potion * a gem ? a scroll = a ring / a wand [ a suit of armor ) a weapon ( a useful item (camera, key, rope etc.) 0 an iron ball _ an iron chain " an amulet , a trapper : a chameleon ~ a lurker above & a demon A a giant ant B a giant bat C a centaur; Of all the monsters put together by the Greek imagination the Centaurs (Kentauroi) constituted a class in themselves. Despite a strong streak of sensuality in their make-up, their normal behaviour was moral, and they took a kindly thought of man's welfare. The attempted outrage of Nessos on Deianeira, and that of the whole tribe of Centaurs on the Lapith women, are more than offset by the hospitality of Pholos and by the wisdom of Cheiron, physician, prophet, lyrist, and the instructor of Achilles. Further, the Cen- taurs were peculiar in that their nature, which united the body of a horse with the trunk and head of a man, involved an unthinkable duplication of vital organs and important members. So grotesque a combination seems almost un-Greek. These strange creatures were said to live in the caves and clefts of the mountains, myths associating them especially with the hills of Thessaly and the range of Erymanthos. [Mythology of all races, Vol. 1, pp. 270-271] D a dragon E a floating eye F a freezing sphere G a gnome H a hobgoblin; Hobgoblin. Used by the Puritans and in later times for wicked goblin spirits, as in Bunyan's 'Hobgoblin nor foul friend', but its more correct use is for the friendly spir- its of the brownie type. In 'A midsummer night's dream' a fairy says to Shakespeare's Puck: Those that Hobgoblin call you, and sweet Puck, You do their work, and they shall have good luck: Are you not he? and obviously Puck would not wish to be called a hobgoblin if that was an ill-omened word. Hobgoblins are on the whole, good-humoured and ready to be helpful, but fond of practical joking, and like most of the fairies rather nasty people to annoy. Boggarts hover on the verge of hobgoblindom. Bogles are just over the edge. One Hob mentioned by Henderson, was Hob Headless who haunted the road between Hurworth and Neasham, but could not cross the little river Kent, which flowed into the Tess. He was exorcised and laid under a large stone by the roadside for ninety-nine years and a day. If anyone was so unwary as to sit on that stone, he would be unable to quit it for ever. The ninety-nine years is nearly up, so trouble may soon be heard of on the road between Hurworth and Neasham. [Katharine Briggs, A dictionary of Fairies] I an invisible stalker J a jackal K a kobold L a leprechaun; The Irish Leprechaun is the Faeries' shoemaker and is known under various names in different parts of Ireland: Cluri- caune in Cork, Lurican in Kerry, Lurikeen in Kildare and Lu- rigadaun in Tipperary. Although he works for the Faeries, the Leprechaun is not of the same species. He is small, has dark skin and wears strange clothes. His nature has some- thing of the manic-depressive about it: first he is quite happy, whistling merrily as he nails a sole on to a shoe; a few minutes later, he is sullen and morose, drunk on his home-made heather ale. The Leprechaun's two great loves are tobacco and whiskey, and he is a first-rate con-man, impos- sible to out-fox. No one, no matter how clever, has ever managed to cheat him out of his hidden pot of gold or his magic shilling. At the last minute he always thinks of some way to divert his captor's attention and vanishes in the twinkling of an eye. [From: A Field Guide to the Little People by Nancy Arrowsmith & George Moorse. ] M a mimic N a nymph O an orc P a purple worm Q a quasit R a rust monster S a snake T a troll U an umber hulk V a vampire W a wraith X a xorn Y a yeti Z a zombie a an acid blob b a giant beetle c a cockatrice; Once in a great while, when the positions of the stars are just right, a seven-year-old rooster will lay an egg. Then, along will come a snake, to coil around the egg, or a toad, to squat upon the egg, keeping it warm and helping it to hatch. When it hatches, out comes a creature called basil- isk, or cockatrice, the most deadly of all creatures. A sin- gle glance from its yellow, piercing toad's eyes will kill both man and beast. Its power of destruction is said to be so great that sometimes simply to hear its hiss can prove fatal. Its breath is so venomenous that it causes all vege- tation to wither. There is, however, one creature which can withstand the basilisk's deadly gaze, and this is the weasel. No one knows why this is so, but although the fierce weasel can slay the basilisk, it will itself be killed in the struggle. Perhaps the weasel knows the basilisk's fatal weakness: if it ever sees its own reflection in a mirror it will perish instant- ly. But even a dead basilisk is dangerous, for it is said that merely touching its lifeless body can cause a person to sicken and die. [From: Mythical Beasts by Deirdre Headon (The Leprechaun Library) and other sources. ] d a dog e an ettin f a fog cloud g a gelatinous cube h a homunculus i an imp; An 'imp' is an off-shoot or cutting. Thus an 'ymp tree' was a grafted tree, or one grown from a cutting, not from seed. 'Imp' properly means a small devil, an off-shoot of Satan, but the distinction between goblins or bogles and imps from hell is hard to make, and many in the Celtic countries as well as the English Puritans regarded all fairies as devils. The fairies of tradition often hover uneasily between the ghostly and the diabolic state. [Katharine Briggs, A dictionary of Fairies] j a jaguar k a killer bee l a leocrotta m a minotaur n a nurse o an owlbear p a piercer q a quivering blob r a giant rat s a scorpion t a tengu; The tengu was the most troublesome creature of Japanese legend. Part bird and part man, with red beak for a nose and flashing eyes, the tengu was notorious for stirring up feuds and prolonging enmity between families. Indeed, the belligerent tengus were supposed to have been man's first instructors in the use of arms. [From: Mythical Beasts by Deirdre Headon (The Leprechaun Library). ] u a unicorn; Men have always sought the elusive unicorn, for the single twisted horn which projected from its forehead was thought to be a powerful talisman. It was said that the unicorn had simply to dip the tip of its horn in a muddy pool for the water to become pure. Men also believed that to drink from this horn was a protection against all sickness, and that if the horn was ground to a powder it would act as an antidote to all poisons. Less than 200 years ago in France, the horn of a unicorn was used in a ceremony to test the royal food for poison. Although only the size of a small horse, the unicorn is a very fierce beast, capable of killing an elephant with a single thrust from its horn. Its fleetness of foot also makes this solitary creature difficult to capture. However, it can be tamed and captured by a maiden. Made gentle by the sight of a virgin, the unicorn can be lured to lay its head in her lap, and in this docile mood, the maiden may secure it with a golden rope. [From: Mythical Beasts by Deirdre Headon (The Leprechaun Library). ] v a violet fungi w a long worm; From its teeth the crysknife can be manufactured. x a xan; The xan were animals sent to prick the legs of the Lords of Xibalba. y a yellow light z a zruty; The zruty are wild and gigantic beings, living in the wildernesses of the Tatra mountains. //E*O*F data// echo x - date.h cat > "date.h" << '//E*O*F date.h//' char datestring[] = "Mon Dec 17 1984"; //E*O*F date.h// exit 0