From ino-news@kabelmail.de  Mon Sep 29 20:16:55 2008
Return-Path: <ino-news@kabelmail.de>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id AC81D106569A
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 29 Sep 2008 20:16:55 +0000 (UTC)
	(envelope-from ino-news@kabelmail.de)
Received: from smtpa.mediabeam.com (smtpa1.mediabeam.com [194.25.41.13])
	by mx1.freebsd.org (Postfix) with ESMTP id 2EBCD8FC1D
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 29 Sep 2008 20:16:54 +0000 (UTC)
	(envelope-from ino-news@kabelmail.de)
Received: from spotteswoode.dnsalias.org (91-64-168-90-dynip.superkabel.de [91.64.168.90])
	(authenticated bits=0)
	by smtpa.mediabeam.com (8.13.1/8.13.1) with ESMTP id m8TJugUv007215
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 29 Sep 2008 21:56:42 +0200
Received: by spotteswoode.dnsalias.org (Postfix, from userid 0)
	id 1B24AAC897; Mon, 29 Sep 2008 21:54:46 +0200 (CEST)
Message-Id: <20080929195446.1B24AAC897@spotteswoode.dnsalias.org>
Date: Mon, 29 Sep 2008 21:54:46 +0200 (CEST)
From: clemens fischer <ino-news@spotteswoode.dnsalias.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc: clemens fischer <ino-news@spotteswoode.dnsalias.org>
Subject: ports/games/freebsd-games doesn't build, and larn(6) segfaults!
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         127728
>Category:       ports
>Synopsis:       ports/games/bsdgames doesn't build, and larn(6) segfaults!
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Sep 29 20:20:00 UTC 2008
>Closed-Date:    Mon Dec 21 10:44:07 UTC 2009
>Last-Modified:  Mon Dec 21 10:44:07 UTC 2009
>Originator:     clemens fischer
>Release:        FreeBSD 8.0-CURRENT i386
>Organization:
>Environment:
System: FreeBSD spotteswoode.dnsalias.org 8.0-CURRENT FreeBSD
8.0-CURRENT #3 r183438M: Sun Sep 28 20:40:36 CEST 2008
root@spotteswoode.dnsalias.org:/usr/obj/usr/src-main/sys/spott_fbsd8_i386

>Description:

people!  larn(6) of the freebsd games collection has ceased to function,
has ceased to provide us old folks with that cosy feeling of ... sorry,
i can't speak anymore ...

At first, I didn't want to alarm anyone:  It got into trouble on the
7 -> 8 transition or when the compiler got the big 4 in its version.

symptom:  segfaults whenever restoring a previous game or when reading
scrolls, right after the first few moves.  I cannot precisely locate the
problem, even after using CFLAGS=-g on it.

when trying to build the port, this is what happens (although i'm only
interested in larn(6), atc(6) comes first in the build and doesn't even
compile):

...
cd atc && make depend && make all
yacc -d grammar.y
cp y.tab.c grammar.c
lex -t  lex.l > lex.c
rm -f .depend
mkdep -f .depend -a     extern.c grammar.c graphics.c input.c lex.c list.c log.c main.c tunable.c update.c
echo atc: /usr/lib/libc.a /usr/lib/libl.a /usr/lib/libm.a /usr/lib/libcurses.a >> .depend
Warning: Object directory not changed from original /usr/ports/games/freebsd-games/work/freebsd-games-5.1.1/atc
cc -g -c extern.c
extern.c:68: error: storage size of 'tty_start' isn't known
*** Error code 1
...

>How-To-Repeat:

for the build, just try to "make" in the ports directory.  for larn(6),
cd into its directory, make(1) there and try it out with "./larn" and
doing some moves.

regards, clemens
>Fix:
>Release-Note:
>Audit-Trail:

From: clemens fischer <ino-news@spotteswoode.dnsalias.org>
To: bug-followup@freebsd.org, ino-news@spotteswoode.dnsalias.org
Cc:  
Subject: [patch] Re: ports/127728: ports/games/freebsd-games doesn't build,
	and larn(6) segfaults!
Date: Thu, 30 Oct 2008 22:42:46 +0100

 --kfjH4zxOES6UT95V
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 hi,
 
 when thinking about fixing our freebsd-games, I came about the following
 problem:  to fully verify correct operation, I'd have to play all the
 games, since they have no test-harness!  This is impossible for me to
 do.
 
 I only play larn(6), but my patch fixes it.  In addition, it defines
 a knob "SWAP_YZ", which changes the hardcoded key mappings in order for
 people to play on eg. german keyboards with 'y' and 'z' exchanged.
 
 My biggest problem was reading and understanding the code, so I had to
 clean it up a little.  Unfortunately, it makes the diff larger than it
 needs to be.  It is attached.
 
 
 regards, clemens
 
 --kfjH4zxOES6UT95V
 Content-Type: text/x-diff; charset=us-ascii
 Content-Disposition: attachment; filename="larn-spott.diff"
 
 diff --git a/work/freebsd-games-5.1.1/larn/Makefile b/work/freebsd-games-5.1.1/larn/Makefile
 --- a/work/freebsd-games-5.1.1/larn/Makefile
 +++ b/work/freebsd-games-5.1.1/larn/Makefile
 @@ -55,6 +55,9 @@
  PROG=	larn
  MAN=	larn.6
  CFLAGS+=-DPOSIX -DVER=12 -DSUBVER=0 -DNONAP -DUIDSCORE -DNOVARARGS
 +.ifdef SWAP_YZ
 +CFLAGS+=-DSWAP_YZ
 +.endif
  SRCS=	main.c object.c create.c tok.c display.c global.c data.c io.c \
  	monster.c store.c diag.c help.c config.c nap.c bill.c scores.c \
  	signal.c moreobj.c movem.c regen.c fortune.c savelev.c
 diff --git a/work/freebsd-games-5.1.1/larn/data.c b/work/freebsd-games-5.1.1/larn/data.c
 --- a/work/freebsd-games-5.1.1/larn/data.c
 +++ b/work/freebsd-games-5.1.1/larn/data.c
 @@ -194,7 +194,7 @@
    "","","","","","","","","","","","","","","","","","","",""
   };
  
 -
 +
  /*
   *	for the monster data
   *
 @@ -299,77 +299,81 @@
  
  /*	name array for scrolls		*/
  
 -char *scrollname[] = {
 -"\0enchant armor",
 -"\0enchant weapon",
 -"\0enlightenment",
 -"\0blank paper",
 -"\0create monster",
 -"\0create artifact",
 -"\0aggravate monsters",
 -"\0time warp",
 -"\0teleportation",
 -"\0expanded awareness",
 -"\0haste monsters",
 -"\0monster healing",
 -"\0spirit protection",
 -"\0undead protection",
 -"\0stealth",
 -"\0magic mapping",
 -"\0hold monsters",
 -"\0gem perfection",
 -"\0spell extension",
 -"\0identify",
 -"\0remove curse",
 -"\0annihilation",
 -"\0pulverization",
 -"\0life protection",
 -"\0 ",
 -"\0 ",
 -"\0 ",
 -"\0 "
 - };
 +struct scroll_or_potion
 +scrollname[] = {
 +    { VALID, "enchant armor" },
 +    { VALID, "enchant weapon" },
 +    { VALID, "enlightenment" },
 +    { VALID, "blank paper" },
 +    { VALID, "create monster" },
 +    { VALID, "create artifact" },
 +    { VALID, "aggravate monsters" },
 +    { VALID, "time warp" },
 +    { VALID, "teleportation" },
 +    { VALID, "expanded awareness" },
 +    { VALID, "haste monsters" },
 +    { VALID, "monster healing" },
 +    { VALID, "spirit protection" },
 +    { VALID, "undead protection" },
 +    { VALID, "stealth" },
 +    { VALID, "magic mapping" },
 +    { VALID, "hold monsters" },
 +    { VALID, "gem perfection" },
 +    { VALID, "spell extension" },
 +    { VALID, "identify" },
 +    { VALID, "remove curse" },
 +    { VALID, "annihilation" },
 +    { VALID, "pulverization" },
 +    { VALID, "life protection" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +};
  
 -/*	name array for magic potions	*/
 -char *potionname[] = {
 -"\0sleep",
 -"\0healing",
 -"\0raise level",
 -"\0increase ability",
 -"\0wisdom",
 -"\0strength",
 -"\0raise charisma",
 -"\0dizziness",
 -"\0learning",
 -"\0gold detection",
 -"\0monster detection",
 -"\0forgetfulness",
 -"\0water",
 -"\0blindness",
 -"\0confusion",
 -"\0heroism",
 -"\0sturdiness",
 -"\0giant strength",
 -"\0fire resistance",
 -"\0treasure finding",
 -"\0instant healing",
 -" cure dianthroritis",
 -"\0poison",
 -"\0see invisible",
 -"\0 ",
 -"\0 ",
 -"\0 ",
 -"\0 ",
 -"\0 ",
 -"\0 ",
 -"\0 ",
 -"\0 ",
 -"\0 ",
 -"\0 ",
 -"\0 "
 - };
 +/*  name array for magic potions    */
  
 -
 +struct scroll_or_potion
 +potionname[] = {
 +    { VALID, "sleep" },
 +    { VALID, "healing" },
 +    { VALID, "raise level" },
 +    { VALID, "increase ability" },
 +    { VALID, "wisdom" },
 +    { VALID, "strength" },
 +    { VALID, "raise charisma" },
 +    { VALID, "dizziness" },
 +    { VALID, "learning" },
 +    { VALID, "gold detection" },
 +    { VALID, "monster detection" },
 +    { VALID, "forgetfulness" },
 +    { VALID, "water" },
 +    { VALID, "blindness" },
 +    { VALID, "confusion" },
 +    { VALID, "heroism" },
 +    { VALID, "sturdiness" },
 +    { VALID, "giant strength" },
 +    { VALID, "fire resistance" },
 +    { VALID, "treasure finding" },
 +    { VALID, "instant healing" },
 +    { IDENTIFIED, "cure dianthroritis" },
 +    { VALID, "poison" },
 +    { VALID, "see invisible" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +    { SPARE, "" },
 +};
 +
 +
  /*
  	spell data
   */
 diff --git a/work/freebsd-games-5.1.1/larn/diag.c b/work/freebsd-games-5.1.1/larn/diag.c
 --- a/work/freebsd-games-5.1.1/larn/diag.c
 +++ b/work/freebsd-games-5.1.1/larn/diag.c
 @@ -77,18 +77,18 @@
  					(long)((hit+5)/2),(long)max(0,dam+20),(long)(monster[i].hitpoints/(dam+20)+1));
  		}
  
 -	lprcat("\n\nHere's the list of available potions:\n\n");
 -	for (i=0; i<MAXPOTION; i++)	lprintf("%20s\n",&potionname[i][1]);
 -	lprcat("\n\nHere's the list of available scrolls:\n\n");
 -	for (i=0; i<MAXSCROLL; i++)	lprintf("%20s\n",&scrollname[i][1]);
 -	lprcat("\n\nHere's the spell list:\n\n");
 -	lprcat("spell          name           description\n");
 -	lprcat("-------------------------------------------------------------------------------------------\n\n");
 -	for (j=0; j<SPNUM; j++)
 -		{
 -		lprc(' ');	lprcat(spelcode[j]);
 -		lprintf(" %21s  %s\n",spelname[j],speldescript[j]);
 -		}
 +    lprcat("\n\nHere's the list of available potions:\n\n");
 +    for (i=0; i<MAXPOTION; i++) lprintf("%20s\n",potionname[i].name);
 +    lprcat("\n\nHere's the list of available scrolls:\n\n");
 +    for (i=0; i<MAXSCROLL; i++) lprintf("%20s\n",scrollname[i].name);
 +    lprcat("\n\nHere's the spell list:\n\n");
 +    lprcat("spell          name           description\n");
 +    lprcat("-------------------------------------------------------------------------------------------\n\n");
 +    for (j=0; j<SPNUM; j++)
 +        {
 +        lprc(' ');  lprcat(spelcode[j]);
 +        lprintf(" %21s  %s\n",spelname[j],speldescript[j]);
 +        }
  
  	lprcat("\n\nFor the c[] array:\n");
  	for (j=0; j<100; j+=10)
 @@ -140,7 +140,7 @@
  		}
  	}
  #endif
 -
 +
  /*
  	to save the game in a file
   */
 @@ -159,31 +159,31 @@
  		nosignal=0;  return(-1);
  		}
  
 -	set_score_output();
 -	lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL);
 -	for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
 -		if (beenhere[k])
 -			lwrite((char*)&cell[k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
 -	times(&cputime);	/* get cpu time */
 -	c[CPUTIME] += (cputime.tms_utime+cputime.tms_stime)/60;
 -	lwrite((char*)&c[0],100*sizeof(long));
 -	lprint((long)gtime);		lprc(level);
 -	lprc(playerx);		lprc(playery);
 -	lwrite((char*)iven,26);	lwrite((char*)ivenarg,26*sizeof(short));
 -	for (k=0; k<MAXSCROLL; k++)  lprc(scrollname[k][0]);
 -	for (k=0; k<MAXPOTION; k++)  lprc(potionname[k][0]);
 -	lwrite((char*)spelknow,SPNUM);		 lprc(wizard);
 -	lprc(rmst);		/*	random monster generation counter */
 -	for (i=0; i<90; i++)	lprc(itm[i].qty);
 -	lwrite((char*)course,25);			lprc(cheat);		lprc(VERSION);
 -	for (i=0; i<MAXMONST; i++) lprc(monster[i].genocided); /* genocide info */
 -	for (sp=spheres; sp; sp=sp->p)
 -		lwrite((char*)sp,sizeof(struct sphere));	/* save spheres of annihilation */
 -	time(&zzz);			lprint((long)(zzz-initialtime));
 -	lwrite((char*)&zzz,sizeof(long));
 -	if (fstat(lfd,&statbuf)< 0) lprint(0L);
 -	else lprint((long)statbuf.st_ino); /* inode # */
 -	lwclose();	lastmonst[0] = 0;
 +    set_score_output();
 +    lwrite((char*)beenhere,MAXLEVEL+MAXVLEVEL);
 +    for (k=0; k<MAXLEVEL+MAXVLEVEL; k++)
 +        if (beenhere[k])
 +            lwrite((char*)&cell[k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
 +    times(&cputime);    /* get cpu time */
 +    c[CPUTIME] += (cputime.tms_utime+cputime.tms_stime)/60;
 +    lwrite((char*)&c[0],100*sizeof(long));
 +    lprint((long)gtime);        lprc(level);
 +    lprc(playerx);      lprc(playery);
 +    lwrite((char*)iven,26); lwrite((char*)ivenarg,26*sizeof(short));
 +    for (k=0; k<MAXSCROLL; k++)  lprc(scrollname[k].flag);
 +    for (k=0; k<MAXPOTION; k++)  lprc(potionname[k].flag);
 +    lwrite((char*)spelknow,SPNUM);       lprc(wizard);
 +    lprc(rmst);     /*  random monster generation counter */
 +    for (i=0; i<90; i++)    lprc(itm[i].qty);
 +    lwrite((char*)course,25);           lprc(cheat);        lprc(VERSION);
 +    for (i=0; i<MAXMONST; i++) lprc(monster[i].genocided); /* genocide info */
 +    for (sp=spheres; sp; sp=sp->p)
 +        lwrite((char*)sp,sizeof(struct sphere));    /* save spheres of annihilation */
 +    time(&zzz);         lprint((long)(zzz-initialtime));
 +    lwrite((char*)&zzz,sizeof(long));
 +    if (fstat(lfd,&statbuf)< 0) lprint(0L);
 +    else lprint((long)statbuf.st_ino); /* inode # */
 +    lwclose();  lastmonst[0] = 0;
  #ifndef VT100
  	setscroll();
  #endif /* VT100 */
 @@ -209,23 +214,34 @@
  		if (beenhere[k])
  			lrfill((char*)&cell[k*MAXX*MAXY],sizeof(struct cel)*MAXY*MAXX);
  
 -	lrfill((char*)&c[0],100*sizeof(long));	gtime = lrint_x();
 -	level = c[CAVELEVEL] = lgetc();
 -	playerx = lgetc();		playery = lgetc();
 -	lrfill((char*)iven,26);		lrfill((char*)ivenarg,26*sizeof(short));
 -	for (k=0; k<MAXSCROLL; k++)  scrollname[k][0] = lgetc();
 -	for (k=0; k<MAXPOTION; k++)  potionname[k][0] = lgetc();
 -	lrfill((char*)spelknow,SPNUM);		wizard = lgetc();
 -	rmst = lgetc();			/*	random monster creation flag */
 +    lrfill((char*)&c[0],100*sizeof(long));
 +    gtime = lrint_x();
 +    level = c[CAVELEVEL] = lgetc();
 +    playerx = lgetc();
 +    playery = lgetc();
 +    lrfill((char*)iven,26);
 +    lrfill((char*)ivenarg,26*sizeof(short));
 +    for (k=0; k<MAXSCROLL; k++)
 +        scrollname[k].flag = lgetc();
 +    for (k=0; k<MAXPOTION; k++)
 +        potionname[k].flag = lgetc();
 +    lrfill((char*)spelknow,SPNUM);
 +    wizard = lgetc();
 +    rmst = lgetc();         /*  random monster creation flag */
  
 -	for (i=0; i<90; i++)	itm[i].qty = lgetc();
 -	lrfill((char*)course,25);			cheat = lgetc();
 -	if (VERSION != lgetc())		/*  version number  */
 -		{
 -		cheat=1;
 -		lprcat("Sorry, But your save file is for an older version of larn\n");
 -		nap(2000); c[GOLD]=c[BANKACCOUNT]=0;  died(-266); return;
 -		}
 +    for (i=0; i<90; i++)
 +        itm[i].qty = lgetc();
 +    lrfill((char*)course,25);
 +    cheat = lgetc();
 +    /* version number */
 +    if (VERSION != lgetc()) {
 +        cheat=1;
 +        lprcat("Sorry, But your save file is for an older version of larn\n");
 +        nap(2000);
 +        c[GOLD]=c[BANKACCOUNT]=0;
 +        died(-266);
 +        return;
 +    }
  
  	for (i=0; i<MAXMONST; i++) monster[i].genocided=lgetc(); /* genocide info */
  	for (sp=0,i=0; i<c[SPHCAST]; i++)
 @@ -247,28 +274,38 @@
  	else if (filetimes.st_mtime > zzz) fsorry(); /*	file modify time	*/
  	if (c[HP]<0) { died(284); return; }	/* died a post mortem death */
  
 -	oldx = oldy = 0;
 -	i = lrint_x();  /* inode # */
 -	if (i && (filetimes.st_ino!=i)) fsorry();
 -	lrclose();
 -	if (strcmp(fname,ckpfile) == 0)
 -		{
 -		if (lappend(fname) < 0) fcheat();  else { lprc(' '); lwclose(); }
 -		lcreat((char*)0);
 -		}
 -	else if (unlink(fname) < 0) fcheat(); /* can't unlink save file */
 -/*	for the greedy cheater checker	*/
 -	for (k=0; k<6; k++) if (c[k]>99) greedy();
 -	if (c[HPMAX]>999 || c[SPELLMAX]>125) greedy();
 -	if (c[LEVEL]==25 && c[EXPERIENCE]>skill[24]) /* if patch up lev 25 player */
 -		{
 -		long tmp;
 -		tmp = c[EXPERIENCE]-skill[24]; /* amount to go up */
 -		c[EXPERIENCE] = skill[24];
 -		raiseexperience((long)tmp);
 -		}
 -	getlevel();  lasttime=gtime;
 -	}
 +    oldx = oldy = 0;
 +    i = lrint_x();  /* inode # */
 +    if (i && (filetimes.st_ino!=i))
 +        fsorry();
 +    lrclose();
 +    if (strcmp(fname,ckpfile) == 0) {
 +        if (lappend(fname) < 0)
 +            fcheat();
 +        else {
 +            lprc(' ');
 +            lwclose();
 +        }
 +        lcreat((char*)0);
 +    }
 +    else if (unlink(fname) < 0)
 +        fcheat(); /* can't unlink save file */
 +    /*  for the greedy cheater checker  */
 +    for (k=0; k<6; k++)
 +        if (c[k]>99)
 +            greedy();
 +    if (c[HPMAX]>999 || c[SPELLMAX]>125)
 +        greedy();
 +    /* if patch up lev 25 player */
 +    if (c[LEVEL]==25 && c[EXPERIENCE]>skill[24]) {
 +        long tmp;
 +        tmp = c[EXPERIENCE]-skill[24]; /* amount to go up */
 +        c[EXPERIENCE] = skill[24];
 +        raiseexperience((long)tmp);
 +    }
 +    getlevel();
 +    lasttime=gtime;
 +}
  
  /*
  	subroutine to not allow greedy cheaters
 diff --git a/work/freebsd-games-5.1.1/larn/display.c b/work/freebsd-games-5.1.1/larn/display.c
 --- a/work/freebsd-games-5.1.1/larn/display.c
 +++ b/work/freebsd-games-5.1.1/larn/display.c
 @@ -255,11 +255,11 @@
  							}
  			}
  
 -	resetbold();  if (d_flag)  { always=1; botside(); always=1; bot_linex(); }
 -	oldx=99;
 -	d_xmin = 0 , d_xmax = MAXX , d_ymin = 0 , d_ymax = MAXY; /* for limited screen drawing */
 -	}
 -
 +    resetbold();  if (d_flag)  { always=1; botside(); always=1; bot_linex(); }
 +    oldx=99;
 +    d_xmin = 0 , d_xmax = MAXX , d_ymin = 0 , d_ymax = MAXY; /* for limited screen drawing */
 +    }
 +
  /*
  	showcell(x,y)
  
 @@ -345,29 +345,29 @@
  short diroffx[] = { 0,  0, 1,  0, -1,  1, -1, 1, -1 };
  short diroffy[] = { 0,  1, 0, -1,  0, -1, -1, 1,  1 };
  moveplayer(dir)
 -	int dir;			/*	from = present room #  direction = [1-north]
 -							[2-east] [3-south] [4-west] [5-northeast]
 -							[6-northwest] [7-southeast] [8-southwest]
 -						if direction=0, don't move--just show where he is */
 -	{
 -	int k,m,i,j;
 -	if (c[CONFUSE]) if (c[LEVEL]<rnd(30)) dir=rund(9); /*if confused any dir*/
 -	k = playerx + diroffx[dir];		m = playery + diroffy[dir];
 -	if (k<0 || k>=MAXX || m<0 || m>=MAXY) { nomove=1; return(yrepcount = 0); }
 -	i = item[k][m];			j = mitem[k][m];
 -	if (i==OWALL && c[WTW]==0) { nomove=1;  return(yrepcount = 0); }		/*	hit a wall	*/
 -	if (k==33 && m==MAXY-1 && level==1)
 -		{
 -		newcavelevel(0); for (k=0; k<MAXX; k++) for (m=0; m<MAXY; m++)
 -		if (item[k][m]==OENTRANCE)
 -		  { playerx=k; playery=m; positionplayer();  drawscreen(); return(0); }
 -		}
 -	if (j>0)     { hitmonster(k,m);	return(yrepcount = 0); } /* hit a monster*/
 -	lastpx = playerx;			lastpy = playery;
 -	playerx = k;		playery = m;
 -	if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP && i!=OIVTRAPDOOR) return(yrepcount = 0);  else return(1);
 -	}
 -
 +    int dir;            /*  from = present room #  direction = [1-north]
 +                            [2-east] [3-south] [4-west] [5-northeast]
 +                            [6-northwest] [7-southeast] [8-southwest]
 +                        if direction=0, don't move--just show where he is */
 +    {
 +    int k,m,i,j;
 +    if (c[CONFUSE]) if (c[LEVEL]<rnd(30)) dir=rund(9); /*if confused any dir*/
 +    k = playerx + diroffx[dir];     m = playery + diroffy[dir];
 +    if (k<0 || k>=MAXX || m<0 || m>=MAXY) { nomove=1; return(yrepcount = 0); }
 +    i = item[k][m];         j = mitem[k][m];
 +    if (i==OWALL && c[WTW]==0) { nomove=1;  return(yrepcount = 0); }        /*  hit a wall  */
 +    if (k==33 && m==MAXY-1 && level==1)
 +        {
 +        newcavelevel(0); for (k=0; k<MAXX; k++) for (m=0; m<MAXY; m++)
 +        if (item[k][m]==OENTRANCE)
 +          { playerx=k; playery=m; positionplayer();  drawscreen(); return(0); }
 +        }
 +    if (j>0)     { hitmonster(k,m); return(yrepcount = 0); } /* hit a monster*/
 +    lastpx = playerx;           lastpy = playery;
 +    playerx = k;        playery = m;
 +    if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP && i!=OIVTRAPDOOR) return(yrepcount = 0);  else return(1);
 +    }
 +
  /*
   *	function to show what magic items have been discovered thus far
   *	enter with -1 for just spells, anything else will give scrolls & potions
 @@ -403,21 +403,23 @@
  
  	lincount += 3;  if (count!=0) { count=2;  seepage(); }
  
 -	lprcat("\nThe magic scrolls you have found to date are:\n\n");
 -	count=0;
 -	for (i=0; i<MAXSCROLL; i++)
 -		if (scrollname[i][0])
 -		  if (scrollname[i][1]!=' ')
 -			{ lprintf("%-26s",&scrollname[i][1]);  seepage(); }
 +    lprcat("\nThe magic scrolls you have found to date are:\n\n");
 +    count=0;
 +    for (i=0; i<MAXSCROLL; i++)
 +        if (IS_IDENTIFIED(scrollname[i].flag)) {
 +            lprintf("%-26s",scrollname[i].name);
 +            seepage();
 +        }
  
  	lincount += 3;  if (count!=0) { count=2;  seepage(); }
  
 -	lprcat("\nThe magic potions you have found to date are:\n\n");
 -	count=0;
 -	for (i=0; i<MAXPOTION; i++)
 -		if (potionname[i][0])
 -		  if (potionname[i][1]!=' ')
 -			{ lprintf("%-26s",&potionname[i][1]);  seepage(); }
 +    lprcat("\nThe magic potions you have found to date are:\n\n");
 +    count=0;
 +    for (i=0; i<MAXPOTION; i++)
 +        if (IS_IDENTIFIED(potionname[i].flag)) {
 +            lprintf("%-26s",potionname[i].name);
 +            seepage();
 +        }
  
  	if (lincount!=0) more();	nosignal=0;  setscroll();	drawscreen();
  	}
 diff --git a/work/freebsd-games-5.1.1/larn/global.c b/work/freebsd-games-5.1.1/larn/global.c
 --- a/work/freebsd-games-5.1.1/larn/global.c
 +++ b/work/freebsd-games-5.1.1/larn/global.c
 @@ -27,7 +27,9 @@
  extern char lastmonst[],*what[],*who[];
  extern char winner[];
  extern char logname[],monstlevel[];
 -extern char sciv[SCORESIZE+1][26][2],*potionname[],*scrollname[];
 +extern char sciv[SCORESIZE+1][26][2];
 +extern struct scroll_or_potion potionname[];
 +extern struct scroll_or_potion scrollname[];
  /*
  	***********
  	RAISE LEVEL
 diff --git a/work/freebsd-games-5.1.1/larn/header.h b/work/freebsd-games-5.1.1/larn/header.h
 --- a/work/freebsd-games-5.1.1/larn/header.h
 +++ b/work/freebsd-games-5.1.1/larn/header.h
 @@ -33,7 +33,33 @@
  #define MAXOBJ 93
  	/* the maximum number of objects   n < MAXOBJ */
  
 -/*	this is the structure definition of the monster data	*/
 +/*
 + * SPARE means "spare slot in table"
 + * VALID means "valid object"
 + * IDENTIFIED means "identified object"
 + */
 +#define VALID 0
 +#define SPARE -1
 +#define IDENTIFIED ' '
 +#define IS_VALID(o) ((o) != SPARE)
 +#define IS_IDENTIFIED(o) ((o) == IDENTIFIED)
 +#define MK_IDENTIFIED(o) do { o = IDENTIFIED; } while (0)
 +struct scroll_or_potion {
 +    int flag;
 +    char *name;
 +};
 +
 +#if defined(SWAP_YZ)
 +#define DIRECTION_NW_Y 'Z'
 +#define DIRECTION_NW_y 'z'
 +#define KEY_TELEPORT_Z 'Y'
 +#else /* SWAP_YZ */
 +#define DIRECTION_NW_Y 'Y'
 +#define DIRECTION_NW_y 'y'
 +#define KEY_TELEPORT_Z 'Z'
 +#endif
 +
 +/*  this is the structure definition of the monster data    */
  struct monst
  	{
  	char	*name;
 @@ -341,9 +367,17 @@
  extern char *lpnt,moved[MAXX][MAXY],mitem[MAXX][MAXY],monstlevel[];
  extern char monstnamelist[],nch[],ndgg[],nlpts[],nomove,nosignal,nowelcome;
  extern char nplt[],nsw[],*objectname[];
 -extern char objnamelist[],optsfile[],*potionname[],playerids[],potprob[];
 +extern char objnamelist[];
 +extern char optsfile[];
 +extern char playerids[];
 +extern char potprob[];
  extern char predostuff,psname[],restorflag,savefilename[],scorefile[],scprob[];
 -extern char screen[MAXX][MAXY],*scrollname[],sex,*spelcode[],*speldescript[];
 +extern char screen[MAXX][MAXY];
 +extern char sex;
 +extern char *spelcode[];
 +extern char *speldescript[];
 +extern struct scroll_or_potion scrollname[];
 +extern struct scroll_or_potion potionname[];
  extern char spelknow[],*spelname[],*spelmes[],spelweird[MAXMONST+8][SPNUM];
  extern char splev[],stealth[MAXX][MAXY],to_lower[],to_upper[],wizard;
  extern short diroffx[],diroffy[],hitflag,hit2flag,hit3flag,hitp[MAXX][MAXY];
 diff --git a/work/freebsd-games-5.1.1/larn/io.c b/work/freebsd-games-5.1.1/larn/io.c
 --- a/work/freebsd-games-5.1.1/larn/io.c
 +++ b/work/freebsd-games-5.1.1/larn/io.c
 @@ -343,195 +343,213 @@
   *  Returns 0 if EOF, otherwise the character
   */
  long lgetc()
 +{
 +    int i;
 +    if (ipoint != iepoint)
 +        return(inbuffer[ipoint++]);
 +    if (iepoint!=MAXIBUF)
 +        return(0);
 +    if ((i=read(fd,inbuffer,MAXIBUF))<=0)
      {
 -    int i;
 -    if (ipoint != iepoint)  return(inbuffer[ipoint++]);
 -    if (iepoint!=MAXIBUF)   return(0);
 -    if ((i=read(fd,inbuffer,MAXIBUF))<=0)
 -        {
          if (i!=0)  write(1,"error reading from input file\n",30);
 -		iepoint = ipoint = 0;		return(0);
 -        }
 -    ipoint=1;  iepoint=i;  return(*inbuffer);
 +        iepoint = ipoint = 0;
 +        return(0);
 +    }
 +    ipoint=1;
 +    iepoint=i;
 +    return(*inbuffer);
 +}
 +
 +/*
 + *  long lrint_x()          Read one integer from input buffer
 + *
 + *      +---------+---------+---------+---------+
 + *      |   high  |         |         |   low   |
 + *      |  order  |         |         |  order  |
 + *      |   byte  |         |         |   byte  |
 + *      +---------+---------+---------+---------+
 + *     31  ---  24 23 --- 16 15 ---  8 7  ---   0
 + *
 + *  The save order is low order first, to high order (4 bytes total)
 + *  Returns the int read
 + */
 +long lrint_x()
 +    {
 +    unsigned long i;
 +    i  = 255 & lgetc();             i |= (255 & lgetc()) << 8;
 +    i |= (255 & lgetc()) << 16;     i |= (255 & lgetc()) << 24;
 +    return(i);
      }
  
  /*
 - *	long lrint_x()			Read one integer from input buffer
 + *  lrfill(address,number)          put input bytes into a buffer
 + *      char *address;
 + *      int number;
   *
 - *		+---------+---------+---------+---------+
 - *		|	high  |			|		  |	  low	|
 - *		|  order  |			|		  |  order	|
 - *		|   byte  |			|		  |	  byte	|
 - *		+---------+---------+---------+---------+
 - *	   31  ---  24 23 --- 16 15 ---  8 7  ---   0
 - *
 - *	The save order is low order first, to high order (4 bytes total)
 - *	Returns the int read
 + *  Reads "number" bytes into the buffer pointed to by "address".
 + *  Returns nothing of value
   */
 -long lrint_x()
 -	{
 -	unsigned long i;
 -	i  = 255 & lgetc();				i |= (255 & lgetc()) << 8;
 -	i |= (255 & lgetc()) << 16;		i |= (255 & lgetc()) << 24;
 -	return(i);
 -	}
 +lrfill(adr,num)
 +    char *adr;
 +    int num;
 +    {
 +    char *pnt;
 +    int num2;
 +    while (num)
 +        {
 +        if (iepoint == ipoint)
 +            {
 +            if (num>5) /* fast way */
 +                {
 +                if (read(fd,adr,num) != num)
 +                    write(2,"error reading from input file\n",30);
 +                num=0;
 +                }
 +            else { *adr++ = lgetc();  --num; }
 +            }
 +        else
 +            {
 +            num2 = iepoint-ipoint;  /*  # of bytes left in the buffer   */
 +            if (num2 > num) num2=num;
 +            pnt = inbuffer+ipoint;  num -= num2;  ipoint += num2;
 +            while (num2--)  *adr++ = *pnt++;
 +            }
 +        }
 +    }
  
  /*
 - *	lrfill(address,number)			put input bytes into a buffer
 - *		char *address;
 - *		int number;
 + *  char *lgetw()           Get a whitespace ended word from input
   *
 - *	Reads "number" bytes into the buffer pointed to by "address".
 - *	Returns nothing of value
 + *  Returns pointer to a buffer that contains word.  If EOF, returns a NULL
   */
 -lrfill(adr,num)
 -	char *adr;
 -	int num;
 -	{
 -	char *pnt;
 -	int num2;
 -	while (num)
 -		{
 -		if (iepoint == ipoint)
 -			{
 -			if (num>5) /* fast way */
 -				{
 -				if (read(fd,adr,num) != num)
 -					write(2,"error reading from input file\n",30);
 -				num=0;
 -				}
 -			else { *adr++ = lgetc();  --num; }
 -			}
 -		else
 -			{
 -			num2 = iepoint-ipoint;	/*	# of bytes left in the buffer	*/
 -			if (num2 > num) num2=num;
 -			pnt = inbuffer+ipoint;	num -= num2;  ipoint += num2;
 -			while (num2--)  *adr++ = *pnt++;
 -			}
 -		}
 -	}
 +char *lgetw()
 +{
 +    char *lgp;
 +    long cc; /* return type of lgetc() */
 +    int n=LINBUFSIZE, quote=0;
 +    lgp = lgetwbuf;
 +    do
 +        cc=lgetc();
 +    while ((cc <= 32) && (cc > (long)NULL));  /* eat whitespace */
 +    for ( ; ; --n,cc=lgetc())
 +    {
 +        if ((cc==(long)NULL) && (lgp==lgetwbuf))
 +            return(NULL);   /* EOF */
 +        if ((n<=1) || ((cc<=32) && (quote==0))) {
 +            *lgp=(char *)NULL;
 +            return(lgetwbuf);
 +        }
 +        if (cc != '"')
 +            *lgp++ = cc;
 +        else quote ^= 1;
 +    }
 +}
  
  /*
 - *	char *lgetw()			Get a whitespace ended word from input
 + *  char *lgetl()       Function to read in a line ended by newline or EOF
   *
 - *	Returns pointer to a buffer that contains word.  If EOF, returns a NULL
 + *  Returns pointer to a buffer that contains the line.  If EOF, returns NULL
   */
 -char *lgetw()
 -	{
 -	char *lgp,cc;
 -	int n=LINBUFSIZE,quote=0;
 -	lgp = lgetwbuf;
 -	do cc=lgetc();  while ((cc <= 32) && (cc > NULL));  /* eat whitespace */
 -	for ( ; ; --n,cc=lgetc())
 -		{
 -		if ((cc==NULL) && (lgp==lgetwbuf))  return(NULL);	/* EOF */
 -		if ((n<=1) || ((cc<=32) && (quote==0))) { *lgp=NULL; return(lgetwbuf); }
 -		if (cc != '"') *lgp++ = cc;   else quote ^= 1;
 -		}
 -	}
 +char *lgetl()
 +{
 +    int i=LINBUFSIZE;
 +    long ch;
 +    char *str=lgetwbuf;
 +    for ( ; ; --i)
 +    {
 +        if ((*str++ = ch = lgetc()) == NULL)
 +        {
 +            if (str == lgetwbuf+1)
 +                return(NULL); /* EOF */
 +ot:         *str = (char *)NULL;
 +            return(lgetwbuf);   /* line ended by EOF */
 +        }
 +        if ((ch=='\n') || (i<=1))
 +            goto ot; /* line ended by \n */
 +    }
 +}
  
  /*
 - *	char *lgetl()		Function to read in a line ended by newline or EOF
 + *  lcreat(filename)            Create a new file for write
 + *      char *filename;
   *
 - *	Returns pointer to a buffer that contains the line.  If EOF, returns NULL
 + *  lcreat((char*)0); means to the terminal
 + *  Returns -1 if error, otherwise the file descriptor opened.
   */
 -char *lgetl()
 -	{
 -	int i=LINBUFSIZE,ch;
 -	char *str=lgetwbuf;
 -	for ( ; ; --i)
 -		{
 -		if ((*str++ = ch = lgetc()) == NULL)
 -			{
 -			if (str == lgetwbuf+1)  return(NULL); /* EOF */
 -		ot:	*str = NULL;	return(lgetwbuf);	/* line ended by EOF */
 -			}
 -		if ((ch=='\n') || (i<=1))  goto ot; /* line ended by \n */
 -		}
 -	}
 +lcreat(str)
 +    char *str;
 +    {
 +    lpnt = lpbuf;   lpend = lpbuf+BUFBIG;
 +    if (str==NULL) return(lfd=1);
 +    if ((lfd=creat(str,0644)) < 0)
 +        {
 +        lfd=1; lprintf("error creating file <%s>\n",str); lflush(); return(-1);
 +        }
 +    return(lfd);
 +    }
  
  /*
 - *	lcreat(filename)			Create a new file for write
 - *		char *filename;
 + *  lopen(filename)         Open a file for read
 + *      char *filename;
   *
 - *	lcreat((char*)0); means to the terminal
 - *	Returns -1 if error, otherwise the file descriptor opened.
 + *  lopen(0) means from the terminal
 + *  Returns -1 if error, otherwise the file descriptor opened.
   */
 -lcreat(str)
 -	char *str;
 -	{
 -	lpnt = lpbuf;	lpend = lpbuf+BUFBIG;
 -	if (str==NULL) return(lfd=1);
 -	if ((lfd=creat(str,0644)) < 0)
 -		{
 -		lfd=1; lprintf("error creating file <%s>\n",str); lflush(); return(-1);
 -		}
 -	return(lfd);
 -	}
 +lopen(str)
 +    char *str;
 +    {
 +    ipoint = iepoint = MAXIBUF;
 +    if (str==NULL) return(fd=0);
 +    if ((fd=open(str,0)) < 0)
 +        {
 +        lwclose(); lfd=1; lpnt=lpbuf; return(-1);
 +        }
 +    return(fd);
 +    }
  
  /*
 - *	lopen(filename)			Open a file for read
 - *		char *filename;
 + *  lappend(filename)       Open for append to an existing file
 + *      char *filename;
   *
 - *	lopen(0) means from the terminal
 - *	Returns -1 if error, otherwise the file descriptor opened.
 + *  lappend(0) means to the terminal
 + *  Returns -1 if error, otherwise the file descriptor opened.
   */
 -lopen(str)
 -	char *str;
 -	{
 -	ipoint = iepoint = MAXIBUF;
 -	if (str==NULL) return(fd=0);
 -	if ((fd=open(str,0)) < 0)
 -		{
 -		lwclose(); lfd=1; lpnt=lpbuf; return(-1);
 -		}
 -	return(fd);
 -	}
 +lappend(str)
 +    char *str;
 +    {
 +    lpnt = lpbuf;   lpend = lpbuf+BUFBIG;
 +    if (str==NULL) return(lfd=1);
 +    if ((lfd=open(str,2)) < 0)
 +        {
 +        lfd=1; return(-1);
 +        }
 +    lseek(lfd,0,2); /* seek to end of file */
 +    return(lfd);
 +    }
  
  /*
 - *	lappend(filename)		Open for append to an existing file
 - *		char *filename;
 + *  lrclose()                       close the input file
   *
 - *	lappend(0) means to the terminal
 - *	Returns -1 if error, otherwise the file descriptor opened.
 + *  Returns nothing of value.
   */
 -lappend(str)
 -	char *str;
 -	{
 -	lpnt = lpbuf;	lpend = lpbuf+BUFBIG;
 -	if (str==NULL) return(lfd=1);
 -	if ((lfd=open(str,2)) < 0)
 -		{
 -		lfd=1; return(-1);
 -		}
 -	lseek(lfd,0,2);	/* seek to end of file */
 -	return(lfd);
 -	}
 +lrclose()
 +    {
 +    if (fd > 0) close(fd);
 +    }
  
  /*
 - *	lrclose()						close the input file
 + *  lwclose()                       close output file flushing if needed
   *
   *	Returns nothing of value.
   */
 -lrclose()
 -	{
 -	if (fd > 0) close(fd);
 -	}
 +lwclose()
 +    {
 +    lflush();   if (lfd > 2) close(lfd);
 +    }
  
  /*
 - *	lwclose()						close output file flushing if needed
 - *
 - *	Returns nothing of value.
 - */
 -lwclose()
 -	{
 -	lflush();	if (lfd > 2) close(lfd);
 -	}
 -
 -/*
 - *	lprcat(string)					append a string to the output buffer
 - *								    avoids calls to lprintf (time consuming)
 + *  lprcat(string)                  append a string to the output buffer
 + *                                  avoids calls to lprintf (time consuming)
   */
  lprcat(str)
      char *str;
 diff --git a/work/freebsd-games-5.1.1/larn/main.c b/work/freebsd-games-5.1.1/larn/main.c
 --- a/work/freebsd-games-5.1.1/larn/main.c
 +++ b/work/freebsd-games-5.1.1/larn/main.c
 @@ -188,47 +188,47 @@
  		}
  #endif /* HIDEBYLINK */
  
 -	if (access(savefilename,0)==0)	/* restore game if need to */
 -		{
 -		clear();	restorflag = 1;
 -		hitflag=1;	restoregame(savefilename);  /* restore last game	*/
 -		}
 -	sigsetup();		/* trap all needed signals	*/
 -	sethard(hard);	/* set up the desired difficulty				*/
 -	setupvt100();	/*	setup the terminal special mode				*/
 -	if (c[HP]==0)	/* create new game */
 -		{
 -		makeplayer();	/*	make the character that will play			*/
 -		newcavelevel(0);/*	make the dungeon						 	*/
 -		predostuff = 1;	/* tell signals that we are in the welcome screen */
 -		if (nowelcome==0) welcome();	 /* welcome the player to the game */
 -		}
 -	drawscreen();	/*	show the initial dungeon					*/
 -	predostuff = 2;	/* tell the trap functions that they must do a showplayer()
 -						from here on */
 -	/* nice(1); */	/* games should be run niced */
 -	yrepcount = hit2flag = 0;
 -	while (1)
 -		{
 -		if (dropflag==0) lookforobject(); /* see if there is an object here	*/
 -			else dropflag=0; /* don't show it just dropped an item */
 -		if (hitflag==0) { if (c[HASTEMONST]) movemonst(); movemonst(); }	/*	move the monsters		*/
 -		if (viewflag==0) showcell(playerx,playery); else viewflag=0;	/*	show stuff around player	*/
 -		if (hit3flag) flushall();
 -		hitflag=hit3flag=0;	nomove=1;
 -		bot_linex();	/* update bottom line */
 -		while (nomove)
 -			{
 -			if (hit3flag) flushall();
 -			nomove=0; parse();
 -			}	/*	get commands and make moves	*/
 -		regen();			/*	regenerate hp and spells			*/
 -		if (c[TIMESTOP]==0)
 -			if (--rmst <= 0)
 -				{ rmst = 120-(level<<2); fillmonst(makemonst(level)); }
 -		}
 -	}
 -
 +    if (access(savefilename,0)==0)  /* restore game if need to */
 +        {
 +        clear();    restorflag = 1;
 +        hitflag=1;  restoregame(savefilename);  /* restore last game    */
 +        }
 +    sigsetup();     /* trap all needed signals  */
 +    sethard(hard);  /* set up the desired difficulty                */
 +    setupvt100();   /*  setup the terminal special mode             */
 +    if (c[HP]==0)   /* create new game */
 +        {
 +        makeplayer();   /*  make the character that will play           */
 +        newcavelevel(0);/*  make the dungeon                            */
 +        predostuff = 1; /* tell signals that we are in the welcome screen */
 +        if (nowelcome==0) welcome();     /* welcome the player to the game */
 +        }
 +    drawscreen();   /*  show the initial dungeon                    */
 +    predostuff = 2; /* tell the trap functions that they must do a showplayer()
 +                        from here on */
 +    /* nice(1); */  /* games should be run niced */
 +    yrepcount = hit2flag = 0;
 +    while (1)
 +        {
 +        if (dropflag==0) lookforobject(); /* see if there is an object here */
 +            else dropflag=0; /* don't show it just dropped an item */
 +        if (hitflag==0) { if (c[HASTEMONST]) movemonst(); movemonst(); }    /*  move the monsters       */
 +        if (viewflag==0) showcell(playerx,playery); else viewflag=0;    /*  show stuff around player    */
 +        if (hit3flag) flushall();
 +        hitflag=hit3flag=0; nomove=1;
 +        bot_linex();    /* update bottom line */
 +        while (nomove)
 +            {
 +            if (hit3flag) flushall();
 +            nomove=0; parse();
 +            }   /*  get commands and make moves */
 +        regen();            /*  regenerate hp and spells            */
 +        if (c[TIMESTOP]==0)
 +            if (--rmst <= 0)
 +                { rmst = 120-(level<<2); fillmonst(makemonst(level)); }
 +        }
 +    }
 +
  /*
  	showstr()
  
 @@ -435,13 +435,19 @@
  	}
  
  show1(idx,str2)
 -	int idx;
 -	char *str2[];
 -	{
 -	if (str2==0)  lprintf("\n%c)   %s",idx+'a',objectname[iven[idx]]);
 -	else if (*str2[ivenarg[idx]]==0)  lprintf("\n%c)   %s",idx+'a',objectname[iven[idx]]);
 -	else lprintf("\n%c)   %s of%s",idx+'a',objectname[iven[idx]],str2[ivenarg[idx]]);
 -	}
 +    int idx;
 +    struct scroll_or_potion *str2;
 +    /*char *str2[];*/
 +{
 +    if (str2==0)
 +        lprintf("\n%c)   %s",idx+'a',objectname[iven[idx]]);
 +    /*else if (str2[ivenarg[idx]].flag == 0)*/
 +    else if (! IS_IDENTIFIED(str2[ivenarg[idx]].flag))
 +        lprintf("\n%c)   %s",idx+'a',objectname[iven[idx]]);
 +    else
 +        lprintf("\n%c)   %s of %s",idx+'a',
 +                objectname[iven[idx]], str2[ivenarg[idx]].name);
 +}
  
  show3(index)
  	int index;
 @@ -478,36 +484,38 @@
  		}
  	}
  
 -
 +
  /*
  	parse()
  
  	get and execute a command
   */
  parse()
 -	{
 -	int i,j,k,flag;
 -	while	(1)
 -		{
 -		k = yylex();
 -		switch(k)	/*	get the token from the input and switch on it	*/
 -			{
 -			case 'h':	moveplayer(4);	return;		/*	west		*/
 -			case 'H':	run(4);			return;		/*	west		*/
 -			case 'l':	moveplayer(2);	return;		/*	east		*/
 -			case 'L':	run(2);			return;		/*	east		*/
 -			case 'j':	moveplayer(1);	return;		/*	south		*/
 -			case 'J':	run(1);			return;		/*	south		*/
 -			case 'k':	moveplayer(3);	return;		/*	north		*/
 -			case 'K':	run(3);			return;		/*	north		*/
 -			case 'u':	moveplayer(5);	return;		/*	northeast	*/
 -			case 'U':	run(5);			return;		/*	northeast	*/
 -			case 'y':	moveplayer(6);  return;		/*	northwest	*/
 -			case 'Y':	run(6);			return;		/*	northwest	*/
 -			case 'n':	moveplayer(7);	return;		/*	southeast	*/
 -			case 'N':	run(7);			return;		/*	southeast	*/
 -			case 'b':	moveplayer(8);	return;		/*	southwest	*/
 -			case 'B':	run(8);			return;		/*	southwest	*/
 +    {
 +    int i,j,k,flag;
 +    while   (1)
 +        {
 +        k = yylex();
 +        switch(k)   /*  get the token from the input and switch on it   */
 +            {
 +            case 'h':   moveplayer(4);  return;     /*  west        */
 +            case 'H':   run(4);         return;     /*  west        */
 +            case 'l':   moveplayer(2);  return;     /*  east        */
 +            case 'L':   run(2);         return;     /*  east        */
 +            case 'j':   moveplayer(1);  return;     /*  south       */
 +            case 'J':   run(1);         return;     /*  south       */
 +            case 'k':   moveplayer(3);  return;     /*  north       */
 +            case 'K':   run(3);         return;     /*  north       */
 +            case 'u':   moveplayer(5);  return;     /*  northeast   */
 +            case 'U':   run(5);         return;     /*  northeast   */
 +            case DIRECTION_NW_y:
 +                        moveplayer(6);  return;     /*  northwest   */
 +            case DIRECTION_NW_Y:
 +                        run(6);         return;     /*  northwest   */
 +            case 'n':   moveplayer(7);  return;     /*  southeast   */
 +            case 'N':   run(7);         return;     /*  southeast   */
 +            case 'b':   moveplayer(8);  return;     /*  southwest   */
 +            case 'B':   run(8);         return;     /*  southwest   */
  
  			case '.':	if (yrepcount) viewflag=1; return;		/*	stay here		*/
  
 @@ -537,9 +545,15 @@
  			case 'S':	clear();  lprcat("Saving . . ."); lflush();
  						savegame(savefilename); wizard=1; died(-257);	/*	save the game - doesn't return	*/
  
 -			case 'Z':	yrepcount=0;	if (c[LEVEL]>9) { oteleport(1); return; }
 -						cursors(); lprcat("\nAs yet, you don't have enough experience to use teleportation");
 -						return;	/*	teleport yourself	*/
 +            case KEY_TELEPORT_Z:
 +                        yrepcount=0;
 +                        if (c[LEVEL]>9) {
 +                            oteleport(1);
 +                            return;
 +                        }
 +                        cursors();
 +                        lprcat("\nAs yet, you don't have enough experience to use teleportation");
 +                        return; /*  teleport yourself   */
  
  			case '^':	/* identify traps */  flag=yrepcount=0;  cursors();
  						lprc('\n');  for (j=playery-1; j<playery+2; j++)
 @@ -560,44 +574,44 @@
  						return;
  
  #if WIZID
 -			case '_':	/*	this is the fudge player password for wizard mode*/
 -						yrepcount=0;	cursors(); nomove=1;
 -						if (userid!=wisid)
 -							{
 -							lprcat("Sorry, you are not empowered to be a wizard.\n");
 -							scbr(); /* system("stty -echo cbreak"); */
 -							lflush();  return;
 -							}
 -						if (getpassword()==0)
 -							{
 -							scbr(); /* system("stty -echo cbreak"); */ return;
 -							}
 -						wizard=1;  scbr(); /* system("stty -echo cbreak"); */
 -						for (i=0; i<6; i++)  c[i]=70;  iven[0]=iven[1]=0;
 -						take(OPROTRING,50);   take(OLANCE,25);  c[WIELD]=1;
 -						c[LANCEDEATH]=1;   c[WEAR] = c[SHIELD] = -1;
 -						raiseexperience(6000000L);  c[AWARENESS] += 25000;
 -						{
 -						int i,j;
 -						for (i=0; i<MAXY; i++)
 -							for (j=0; j<MAXX; j++)  know[j][i]=1;
 -						for (i=0; i<SPNUM; i++)	spelknow[i]=1;
 -						for (i=0; i<MAXSCROLL; i++)  scrollname[i][0]=' ';
 -						for (i=0; i<MAXPOTION; i++)  potionname[i][0]=' ';
 -						}
 -						for (i=0; i<MAXSCROLL; i++)
 -						  if (strlen(scrollname[i])>2) /* no null items */
 -							{ item[i][0]=OSCROLL; iarg[i][0]=i; }
 -						for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--)
 -						  if (strlen(potionname[i-MAXX+MAXPOTION])>2) /* no null items */
 -							{ item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; }
 -						for (i=1; i<MAXY; i++)
 -							{ item[0][i]=i; iarg[0][i]=0; }
 -						for (i=MAXY; i<MAXY+MAXX; i++)
 -							{ item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; }
 -						for (i=MAXX+MAXY; i<MAXX+MAXY+MAXY; i++)
 -							{ item[MAXX-1][i-MAXX-MAXY]=i; iarg[MAXX-1][i-MAXX-MAXY]=0; }
 -						c[GOLD]+=25000;	drawscreen();	return;
 +            case '_':   /*  this is the fudge player password for wizard mode*/
 +                        yrepcount=0;    cursors(); nomove=1;
 +                        if (userid!=wisid)
 +                            {
 +                            lprcat("Sorry, you are not empowered to be a wizard.\n");
 +                            scbr(); /* system("stty -echo cbreak"); */
 +                            lflush();  return;
 +                            }
 +                        if (getpassword()==0)
 +                            {
 +                            scbr(); /* system("stty -echo cbreak"); */ return;
 +                            }
 +                        wizard=1;  scbr(); /* system("stty -echo cbreak"); */
 +                        for (i=0; i<6; i++)  c[i]=70;  iven[0]=iven[1]=0;
 +                        take(OPROTRING,50);   take(OLANCE,25);  c[WIELD]=1;
 +                        c[LANCEDEATH]=1;   c[WEAR] = c[SHIELD] = -1;
 +                        raiseexperience(6000000L);  c[AWARENESS] += 25000;
 +                        {
 +                        int i,j;
 +                        for (i=0; i<MAXY; i++)
 +                            for (j=0; j<MAXX; j++)  know[j][i]=1;
 +                        for (i=0; i<SPNUM; i++) spelknow[i]=1;
 +                        for (i=0; i<MAXSCROLL; i++)  MK_IDENTIFIED(scrollname[i].flag);
 +                        for (i=0; i<MAXPOTION; i++)  MK_IDENTIFIED(potionname[i].flag);
 +                        }
 +                        for (i=0; i<MAXSCROLL; i++)
 +                          if (IS_VALID(scrollname[i].flag)) /* no null items */
 +                            { item[i][0]=OSCROLL; iarg[i][0]=i; }
 +                        for (i=MAXX-1; i>MAXX-1-MAXPOTION; i--)
 +                          if (IS_VALID(potionname[i-MAXX+MAXPOTION].flag)) /* no null items */
 +                            { item[i][0]=OPOTION; iarg[i][0]=i-MAXX+MAXPOTION; }
 +                        for (i=1; i<MAXY; i++)
 +                            { item[0][i]=i; iarg[0][i]=0; }
 +                        for (i=MAXY; i<MAXY+MAXX; i++)
 +                            { item[i-MAXY][MAXY-1]=i; iarg[i-MAXY][MAXY-1]=0; }
 +                        for (i=MAXX+MAXY; i<MAXX+MAXY+MAXY; i++)
 +                            { item[MAXX-1][i-MAXX-MAXY]=i; iarg[MAXX-1][i-MAXX-MAXY]=0; }
 +                        c[GOLD]+=25000; drawscreen();   return;
  #endif
  
  			case 'T':	yrepcount=0;	cursors();  if (c[SHIELD] != -1) { c[SHIELD] = -1; lprcat("\nYour shield is off"); bottomline(); } else
 diff --git a/work/freebsd-games-5.1.1/larn/monster.c b/work/freebsd-games-5.1.1/larn/monster.c
 --- a/work/freebsd-games-5.1.1/larn/monster.c
 +++ b/work/freebsd-games-5.1.1/larn/monster.c
 @@ -736,22 +736,23 @@
   */
  static int
  dirsub(x,y)
 -	int *x,*y;
 -	{
 -	int i;
 -	lprcat("\nIn What Direction? ");
 -	for (i=0; ; )
 -		switch(getchar())
 -			{
 -			case 'b':	i++;
 -			case 'n':	i++;
 -			case 'y':	i++;
 -			case 'u':	i++;
 -			case 'h':	i++;
 -			case 'k':	i++;
 -			case 'l':	i++;
 -			case 'j':	i++;		goto out;
 -			};
 +    int *x,*y;
 +    {
 +    int i;
 +    lprcat("\nIn What Direction? ");
 +    for (i=0; ; )
 +        switch(getchar())
 +            {
 +            case 'b':   i++;
 +            case 'n':   i++;
 +            case DIRECTION_NW_y:
 +                        i++;
 +            case 'u':   i++;
 +            case 'h':   i++;
 +            case 'k':   i++;
 +            case 'l':   i++;
 +            case 'j':   i++;        goto out;
 +            };
  out:
  	*x = playerx+diroffx[i];		*y = playery+diroffy[i];
  	vxy(x,y);  return(i);
 diff --git a/work/freebsd-games-5.1.1/larn/object.c b/work/freebsd-games-5.1.1/larn/object.c
 --- a/work/freebsd-games-5.1.1/larn/object.c
 +++ b/work/freebsd-games-5.1.1/larn/object.c
 @@ -21,14 +21,19 @@
  	case OGOLDPILE:	case OMAXGOLD:
  	case OKGOLD:	case ODGOLD:	lprcat("\n\nYou have found some gold!");	ogold(i);	break;
  
 -	case OPOTION:	lprcat("\n\nYou have found a magic potion");
 -				i = iarg[playerx][playery];
 -				if (potionname[i][0]) lprintf(" of %s",&potionname[i][1]);  opotion(i);  break;
 +    case OPOTION:   lprcat("\n\nYou have found a magic potion");
 +                i = iarg[playerx][playery];
 +                if (IS_IDENTIFIED(potionname[i].flag))
 +                    lprintf(" of %s",potionname[i].name);
 +                opotion(i);
 +                break;
  
 -	case OSCROLL:	lprcat("\n\nYou have found a magic scroll");
 -				i = iarg[playerx][playery];
 -				if (scrollname[i][0])	lprintf(" of %s",&scrollname[i][1]);
 -				oscroll(i);  break;
 +    case OSCROLL:   lprcat("\n\nYou have found a magic scroll");
 +                i = iarg[playerx][playery];
 +                if (IS_IDENTIFIED(scrollname[i].flag))
 +                    lprintf(" of %s",scrollname[i].name);
 +                oscroll(i);
 +                break;
  
  	case OALTAR:	if (nearbymonst()) return;
  					lprcat("\n\nThere is a Holy Altar here!"); oaltar(); break;
 @@ -277,7 +282,7 @@
  	ignore();
  	}
  
 -
 +
  /*
  	*******
  	OSTAIRS
 @@ -334,7 +339,7 @@
  		};
  	}
  
 -
 +
  /*
  	*********
  	OTELEPORTER
 @@ -343,23 +348,23 @@
  	subroutine to handle a teleport trap +/- 1 level maximum
   */
  oteleport(err)
 -	int err;
 -	{
 -	int tmp;
 -	if (err) if (rnd(151)<3)  died(264);  /*	stuck in a rock */
 -	c[TELEFLAG]=1;	/*	show ?? on bottomline if been teleported	*/
 -	if (level==0) tmp=0;
 -	else if (level < MAXLEVEL)
 -		{ tmp=rnd(5)+level-3; if (tmp>=MAXLEVEL) tmp=MAXLEVEL-1;
 -			if (tmp<1) tmp=1; }
 -	else
 -		{ tmp=rnd(3)+level-2; if (tmp>=MAXLEVEL+MAXVLEVEL) tmp=MAXLEVEL+MAXVLEVEL-1;
 -			if (tmp<MAXLEVEL) tmp=MAXLEVEL; }
 -	playerx = rnd(MAXX-2);	playery = rnd(MAXY-2);
 -	if (level != tmp)	newcavelevel(tmp);  positionplayer();
 -	draws(0,MAXX,0,MAXY); bot_linex();
 -	}
 -
 +    int err;
 +    {
 +    int tmp;
 +    if (err) if (rnd(151)<3)  died(264);  /*    stuck in a rock */
 +    c[TELEFLAG]=1;  /*  show ?? on bottomline if been teleported    */
 +    if (level==0) tmp=0;
 +    else if (level < MAXLEVEL)
 +        { tmp=rnd(5)+level-3; if (tmp>=MAXLEVEL) tmp=MAXLEVEL-1;
 +            if (tmp<1) tmp=1; }
 +    else
 +        { tmp=rnd(3)+level-2; if (tmp>=MAXLEVEL+MAXVLEVEL) tmp=MAXLEVEL+MAXVLEVEL-1;
 +            if (tmp<MAXLEVEL) tmp=MAXLEVEL; }
 +    playerx = rnd(MAXX-2);  playery = rnd(MAXY-2);
 +    if (level != tmp)   newcavelevel(tmp);  positionplayer();
 +    draws(0,MAXX,0,MAXY); bot_linex();
 +    }
 +
  /*
  	*******
  	OPOTION
 @@ -388,20 +393,20 @@
  	function to drink a potion
   */
  quaffpotion(pot)
 -	int pot;
 -	{
 -	int i,j,k;
 -	if (pot<0 || pot>=MAXPOTION) return; /* check for within bounds */
 -	potionname[pot][0] = ' ';
 -	switch(pot)
 -		{
 -		case 9: lprcat("\nYou feel greedy . . .");   nap(2000);
 -				for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
 -				  if ((item[j][i]==OGOLDPILE) || (item[j][i]==OMAXGOLD))
 -					{
 -					know[j][i]=1; show1cell(j,i);
 -					}
 -				showplayer();  return;
 +    int pot;
 +    {
 +    int i,j,k;
 +    if (pot<0 || pot>=MAXPOTION) return; /* check for within bounds */
 +    MK_IDENTIFIED(potionname[pot].flag);
 +    switch(pot)
 +        {
 +        case 9: lprcat("\nYou feel greedy . . .");   nap(2000);
 +                for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
 +                  if ((item[j][i]==OGOLDPILE) || (item[j][i]==OMAXGOLD))
 +                    {
 +                    know[j][i]=1; show1cell(j,i);
 +                    }
 +                showplayer();  return;
  
  		case 19: lprcat("\nYou feel greedy . . .");   nap(2000);
  				for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
 @@ -483,13 +488,13 @@
  		case 22: lprcat("\nYou feel a sickness engulf you"); /* poison */
  				 c[HALFDAM] += 200 + rnd(200);  return;
  
 -		case 23: lprcat("\nYou feel your vision sharpen");	/* see invisible */
 -				 c[SEEINVISIBLE] += rnd(1000)+400;
 -				 monstnamelist[INVISIBLESTALKER] = 'I';  return;
 -		};
 -	bottomline();		/*	show new stats		*/  return;
 -	}
 -
 +        case 23: lprcat("\nYou feel your vision sharpen");  /* see invisible */
 +                 c[SEEINVISIBLE] += rnd(1000)+400;
 +                 monstnamelist[INVISIBLESTALKER] = 'I';  return;
 +        };
 +    bottomline();       /*  show new stats      */  return;
 +    }
 +
  /*
  	*******
  	OSCROLL
 @@ -547,14 +552,14 @@
  	function to read a scroll
   */
  read_scroll(typ)
 -	int typ;
 -	{
 -	int i,j;
 -	if (typ<0 || typ>=MAXSCROLL) return;  /* be sure we are within bounds */
 -	scrollname[typ][0] = ' ';
 -	switch(typ)
 -	  {
 -	  case 0:	lprcat("\nYour armor glows for a moment");  enchantarmor(); return;
 +    int typ;
 +    {
 +    int i,j;
 +    if (typ<0 || typ>=MAXSCROLL) return;  /* be sure we are within bounds */
 +    MK_IDENTIFIED(scrollname[typ].flag);
 +    switch(typ)
 +      {
 +      case 0:   lprcat("\nYour armor glows for a moment");  enchantarmor(); return;
  
  	  case 1:	lprcat("\nYour weapon glows for a moment"); enchweapon(); return;  /* enchant weapon */
  
 @@ -614,12 +619,14 @@
  	  case 18:	for (i=0; i<11; i++)	c[exten[i]] <<= 1; /* spell extension */
  				break;
  
 -	  case 19:	for (i=0; i<26; i++)	/* identify */
 -					{
 -					if (iven[i]==OPOTION)  potionname[ivenarg[i]][0] = ' ';
 -					if (iven[i]==OSCROLL)  scrollname[ivenarg[i]][0] = ' ';
 -					}
 -				break;
 +      case 19:  for (i=0; i<26; i++)    /* identify */
 +                    {
 +                    if (iven[i]==OPOTION)
 +                        MK_IDENTIFIED(potionname[ivenarg[i]].flag);
 +                    if (iven[i]==OSCROLL)
 +                        MK_IDENTIFIED(scrollname[ivenarg[i]].flag);
 +                    }
 +                break;
  
  	  case 20:	for (i=0; i<10; i++)	/* remove curse */
  					if (c[curse[i]]) c[curse[i]] = 1;
 @@ -633,7 +640,7 @@
  	  };
  	}
  
 -
 +
  oorb()
  	{
  	}
 diff --git a/work/freebsd-games-5.1.1/larn/scores.c b/work/freebsd-games-5.1.1/larn/scores.c
 --- a/work/freebsd-games-5.1.1/larn/scores.c
 +++ b/work/freebsd-games-5.1.1/larn/scores.c
 @@ -287,16 +287,23 @@
   *	Returns nothing of value
   */
  showallscores()
 -	{
 -	int i,j;
 -	lflush();  lcreat((char*)0);  if (readboard()<0) return;
 -	c[WEAR] = c[WIELD] = c[SHIELD] = -1;  /* not wielding or wearing anything */
 -	for (i=0; i<MAXPOTION; i++) potionname[i][0]=' ';
 -	for (i=0; i<MAXSCROLL; i++) scrollname[i][0]=' ';
 -	i=winshou();  j=shou(1);
 -	if (i+j==0) lprcat(esb); else lprc('\n');
 -	lflush();
 -	}
 +{
 +    int i,j;
 +    lflush();
 +    lcreat((char*)0);
 +    if (readboard()<0)
 +        return;
 +    c[WEAR] = c[WIELD] = c[SHIELD] = -1;  /* not wielding or wearing anything */
 +    for (i=0; i<MAXPOTION; i++) MK_IDENTIFIED(potionname[i].flag);
 +    for (i=0; i<MAXSCROLL; i++) MK_IDENTIFIED(scrollname[i].flag);
 +    i=winshou();
 +    j=shou(1);
 +    if (i+j==0)
 +        lprcat(esb);
 +    else
 +        lprc('\n');
 +    lflush();
 +}
  
  /*
   *	sortboard()		Function to sort the scoreboard
 diff --git a/work/freebsd-games-5.1.1/larn/store.c b/work/freebsd-games-5.1.1/larn/store.c
 --- a/work/freebsd-games-5.1.1/larn/store.c
 +++ b/work/freebsd-games-5.1.1/larn/store.c
 @@ -101,65 +101,65 @@
  /*cost	  memory 	iven name	iven arg   how
    gp	 pointer	  iven[]	ivenarg[]  many */
  
 -{	20,		potionname,	OPOTION,	0,		6	},
 -{	90,		potionname,	OPOTION,	1,		5	},
 -{	520,	potionname,	OPOTION,	2,		1	},
 -{ 	100,	potionname,	OPOTION,	3,		2	},
 -{	50,		potionname,	OPOTION,	4,		2	},
 -{	150,	potionname,	OPOTION,	5,		2	},
 -{	70,		potionname,	OPOTION,	6,		1	},
 -{	30,		potionname,	OPOTION,	7,		7	},
 -{	200,	potionname,	OPOTION,	8,		1	},
 -{	50,		potionname,	OPOTION,	9,		1	},
 -{	80,		potionname,	OPOTION,	10,		1	},
 +{   20,     (char **)potionname,    OPOTION,    0,      6   },
 +{   90,     (char **)potionname,    OPOTION,    1,      5   },
 +{   520,    (char **)potionname,    OPOTION,    2,      1   },
 +{   100,    (char **)potionname,    OPOTION,    3,      2   },
 +{   50,     (char **)potionname,    OPOTION,    4,      2   },
 +{   150,    (char **)potionname,    OPOTION,    5,      2   },
 +{   70,     (char **)potionname,    OPOTION,    6,      1   },
 +{   30,     (char **)potionname,    OPOTION,    7,      7   },
 +{   200,    (char **)potionname,    OPOTION,    8,      1   },
 +{   50,     (char **)potionname,    OPOTION,    9,      1   },
 +{   80,     (char **)potionname,    OPOTION,    10,     1   },
  
  /*cost	  memory 	iven name	iven arg   how
    gp	 pointer	  iven[]	ivenarg[]  many */
  
 -{	30,		potionname,	OPOTION,	11,		3	},
 -{	20,		potionname,	OPOTION,	12,		5	},
 -{	40,		potionname,	OPOTION,	13,		3	},
 -{	35,		potionname,	OPOTION,	14,		2	},
 -{	520,	potionname,	OPOTION,	15,		1	},
 -{	90,		potionname,	OPOTION,	16,		2	},
 -{	200,	potionname,	OPOTION,	17,		2	},
 -{	220,	potionname,	OPOTION,	18,		4	},
 -{	80,		potionname,	OPOTION,	19,		6	},
 -{	370,	potionname,	OPOTION,	20,		3	},
 -{	50,		potionname,	OPOTION,	22,		1	},
 -{	150,	potionname,	OPOTION,	23,		3	},
 +{   30,     (char **)potionname,    OPOTION,    11,     3   },
 +{   20,     (char **)potionname,    OPOTION,    12,     5   },
 +{   40,     (char **)potionname,    OPOTION,    13,     3   },
 +{   35,     (char **)potionname,    OPOTION,    14,     2   },
 +{   520,    (char **)potionname,    OPOTION,    15,     1   },
 +{   90,     (char **)potionname,    OPOTION,    16,     2   },
 +{   200,    (char **)potionname,    OPOTION,    17,     2   },
 +{   220,    (char **)potionname,    OPOTION,    18,     4   },
 +{   80,     (char **)potionname,    OPOTION,    19,     6   },
 +{   370,    (char **)potionname,    OPOTION,    20,     3   },
 +{   50,     (char **)potionname,    OPOTION,    22,     1   },
 +{   150,    (char **)potionname,    OPOTION,    23,     3   },
  
  /*cost	  memory 	iven name	iven arg   how
    gp	 pointer	  iven[]	ivenarg[]  many */
  
 -{ 100,	scrollname,		OSCROLL,	0,		2	},
 -{ 125,	scrollname,		OSCROLL,	1,		2	},
 -{ 60,	scrollname,		OSCROLL,	2,		4	},
 -{ 10,	scrollname,		OSCROLL,	3,		4	},
 -{ 100,	scrollname,		OSCROLL,	4,		3	},
 -{ 200,	scrollname,		OSCROLL,	5,		2	},
 -{ 110,	scrollname,		OSCROLL,	6,		1	},
 -{ 500,	scrollname,		OSCROLL,	7,		2	},
 -{ 200,	scrollname,		OSCROLL,	8,		2	},
 -{ 250,	scrollname,		OSCROLL,	9,		4	},
 -{ 20,	scrollname,		OSCROLL,	10,		5	},
 -{ 30,	scrollname,		OSCROLL,	11,		3	},
 +{ 100,  (char **)scrollname,        OSCROLL,    0,      2   },
 +{ 125,  (char **)scrollname,        OSCROLL,    1,      2   },
 +{ 60,   (char **)scrollname,        OSCROLL,    2,      4   },
 +{ 10,   (char **)scrollname,        OSCROLL,    3,      4   },
 +{ 100,  (char **)scrollname,        OSCROLL,    4,      3   },
 +{ 200,  (char **)scrollname,        OSCROLL,    5,      2   },
 +{ 110,  (char **)scrollname,        OSCROLL,    6,      1   },
 +{ 500,  (char **)scrollname,        OSCROLL,    7,      2   },
 +{ 200,  (char **)scrollname,        OSCROLL,    8,      2   },
 +{ 250,  (char **)scrollname,        OSCROLL,    9,      4   },
 +{ 20,   (char **)scrollname,        OSCROLL,    10,     5   },
 +{ 30,   (char **)scrollname,        OSCROLL,    11,     3   },
  
  /*cost	  memory 	iven name	iven arg   how
    gp	 pointer	  iven[]	ivenarg[]  many */
  
 -{ 340,	scrollname,		OSCROLL,	12,		1	},
 -{ 340,	scrollname,		OSCROLL,	13,		1	},
 -{ 300,	scrollname,		OSCROLL,	14,		2	},
 -{ 400,	scrollname,		OSCROLL,	15,		2	},
 -{ 500,	scrollname,		OSCROLL,	16,		2	},
 -{ 1000,	scrollname,		OSCROLL,	17,		1	},
 -{ 500,	scrollname,		OSCROLL,	18,		1	},
 -{ 340,	scrollname,		OSCROLL,	19,		2	},
 -{ 220,	scrollname,		OSCROLL,	20,		3	},
 -{ 3900,	scrollname,		OSCROLL,	21,		0	},
 -{ 610,	scrollname,		OSCROLL,	22,		1	},
 -{ 3000,	scrollname,		OSCROLL,	23,		0	}
 +{ 340,  (char **)scrollname,        OSCROLL,    12,     1   },
 +{ 340,  (char **)scrollname,        OSCROLL,    13,     1   },
 +{ 300,  (char **)scrollname,        OSCROLL,    14,     2   },
 +{ 400,  (char **)scrollname,        OSCROLL,    15,     2   },
 +{ 500,  (char **)scrollname,        OSCROLL,    16,     2   },
 +{ 1000, (char **)scrollname,        OSCROLL,    17,     1   },
 +{ 500,  (char **)scrollname,        OSCROLL,    18,     1   },
 +{ 340,  (char **)scrollname,        OSCROLL,    19,     2   },
 +{ 220,  (char **)scrollname,        OSCROLL,    20,     3   },
 +{ 3900, (char **)scrollname,        OSCROLL,    21,     0   },
 +{ 610,  (char **)scrollname,        OSCROLL,    22,     1   },
 +{ 3000, (char **)scrollname,        OSCROLL,    23,     0   }
   };
  
  /*
 @@ -222,42 +222,73 @@
  	drawscreen();  nosignal = 0; /* enable signals */ return;
  	}
  
 -  dnd_hed();
 -  while (1)
 -	{
 -	cursor(59,18); lprintf("%d gold pieces",(long)c[GOLD]);
 -	cltoeoln(); cl_dn(1,20);	/* erase to eod */
 -	lprcat("\nEnter your transaction ["); standout("space");
 -	lprcat(" for more, "); standout("escape");
 -	lprcat(" to leave]? ");
 -	i=0;
 -	while ((i<'a' || i>'z') && (i!=' ') && (i!='\33') && (i!=12))  i=getchar();
 -	if (i==12) { clear();  dnd_2hed();  dnd_hed(); }
 -	else if (i=='\33')
 -		{ drawscreen();  nosignal = 0; /* enable signals */ return; }
 -	else if (i==' ')
 -		{
 -		cl_dn(1,4);
 -		if ((dnditm += 26) >= maxitm) dnditm=0; dnd_hed();
 -		}
 -	else
 -		{  /* buy something */
 -		lprc(i);	/* echo the byte */
 -		i += dnditm - 'a';
 -		if (i>=maxitm) outofstock(); else
 -		if (itm[i].qty <= 0) outofstock(); else
 -		if (pocketfull()) handsfull(); else
 -		if (c[GOLD] < itm[i].price*10) nogold(); else
 -			{
 -			if (itm[i].mem != 0) *itm[i].mem[itm[i].arg] = ' ';
 -			c[GOLD] -= itm[i].price*10;
 -			itm[i].qty--;  take(itm[i].obj,itm[i].arg);
 -			if (itm[i].qty==0) dnditem(i);  nap(1001);
 -			}
 -		}
 -
 -	}
 -  }
 +    dnd_hed();
 +    while (1)
 +    {
 +        cursor(59,18);
 +        lprintf("%d gold pieces",(long)c[GOLD]);
 +        cltoeoln();
 +        cl_dn(1,20);    /* erase to eod */
 +        lprcat("\nEnter your transaction [");
 +        standout("space");
 +        lprcat(" for more, ");
 +        standout("escape");
 +        lprcat(" to leave]? ");
 +        i=0;
 +        while ((i<'a' || i>'z') && (i!=' ') && (i!='\33') && (i!=12))
 +            i=getchar();
 +        if (i==12) {
 +            clear();
 +            dnd_2hed();
 +            dnd_hed();
 +        }
 +        else if (i=='\33') {
 +            drawscreen();
 +            nosignal = 0; /* enable signals */
 +            return;
 +        }
 +        else if (i==' ') {
 +            cl_dn(1,4);
 +            if ((dnditm += 26) >= maxitm)
 +                dnditm=0;
 +            dnd_hed();
 +        }
 +        else {  /* buy something */
 +            lprc(i);    /* echo the byte */
 +            i += dnditm - 'a';
 +            if (i>=maxitm)
 +                outofstock();
 +            else if (itm[i].qty <= 0)
 +                outofstock();
 +            else if (pocketfull())
 +                handsfull();
 +            else if (c[GOLD] < itm[i].price*10)
 +                nogold();
 +            else {
 +                if (itm[i].mem != 0) {
 +                    switch (itm[i].obj) {
 +                        case OSCROLL:
 +                            MK_IDENTIFIED(scrollname[itm[i].arg].flag);
 +                            break;
 +                        case OPOTION:
 +                            MK_IDENTIFIED(potionname[itm[i].arg].flag);
 +                            break;
 +                        default:
 +                            lprcat("\nInternal error: dndstore()!");
 +                            lflush();
 +                            nap(2200);
 +                    }
 +                }
 +                c[GOLD] -= itm[i].price*10;
 +                itm[i].qty--;
 +                take(itm[i].obj,itm[i].arg);
 +                if (itm[i].qty==0)
 +                    dnditem(i);
 +                nap(1001);
 +            }
 +        }
 +    }
 +}
  
  /*
  	dnditem(index)
 @@ -266,22 +297,31 @@
   */
  static void
  dnditem(i)
 -	int i;
 -	{
 -	int j,k;
 -	if (i >= maxitm)  return;
 -	cursor( (j=(i&1)*40+1) , (k=((i%26)>>1)+5) );
 -	if (itm[i].qty == 0)  { lprintf("%39s","");  return; }
 -	lprintf("%c) ",(i%26)+'a');
 -	if (itm[i].obj == OPOTION)
 -		{ lprcat("potion of "); lprintf("%s",&potionname[itm[i].arg][1]); }
 -	else if (itm[i].obj == OSCROLL)
 -		{ lprcat("scroll of "); lprintf("%s",&scrollname[itm[i].arg][1]); }
 -	else lprintf("%s",objectname[itm[i].obj]);
 -	cursor( j+31,k );  lprintf("%6d",(long)(itm[i].price*10));
 -	}
 +    int i;
 +{
 +    int j,k;
 +    if (i >= maxitm)
 +        return;
 +    cursor( (j=(i&1)*40+1) , (k=((i%26)>>1)+5) );
 +    if (itm[i].qty == 0) {
 +        lprintf("%39s","");
 +        return;
 +    }
 +    lprintf("%c) ",(i%26)+'a');
 +    if (itm[i].obj == OPOTION) {
 +        lprcat("potion of ");
 +        lprintf("%s",potionname[itm[i].arg].name);
 +    }
 +    else if (itm[i].obj == OSCROLL) {
 +        lprcat("scroll of ");
 +        lprintf("%s",scrollname[itm[i].arg].name);
 +    }
 +    else
 +        lprintf("%s",objectname[itm[i].obj]);
 +    cursor( j+31,k );
 +    lprintf("%6d",(long)(itm[i].price*10));
 +}
  
 -
  /*
  	for the college of larn
   */
 @@ -394,15 +434,15 @@
  			  course[i-'a']++;	/*	remember that he has taken that course	*/
  			  c[HP] = c[HPMAX];  c[SPELLS] = c[SPELLMAX]; /* he regenerated */
  
 -			  if (c[BLINDCOUNT])	c[BLINDCOUNT]=1;  /* cure blindness too!  */
 -			  if (c[CONFUSE])		c[CONFUSE]=1;	/*	end confusion	*/
 -			  adjtime((long)time_used);	/* adjust parameters for time change */
 -			  }
 -			nap(1000);
 -			}
 -		}
 -	}
 -
 +              if (c[BLINDCOUNT])    c[BLINDCOUNT]=1;  /* cure blindness too!  */
 +              if (c[CONFUSE])       c[CONFUSE]=1;   /*  end confusion   */
 +              adjtime((long)time_used); /* adjust parameters for time change */
 +              }
 +            nap(1000);
 +            }
 +        }
 +    }
 +
  /*
   *	for the first national bank of Larn
   */
 @@ -590,61 +630,100 @@
  	}
  
  otradepost()
 -  {
 -  int i,j,value,isub,izarg;
 -  dnditm = dndcount = 0;
 -  nosignal = 1; /* disable signals */
 -  resetscroll();	otradhead();
 -  while (1)
 -	{
 -	lprcat("\nWhat item do you want to sell to us ["); standout("*");
 -	lprcat(" for list, or "); standout("escape"); lprcat("] ? ");
 -	i=0; while (i>'z' || (i<'a' && i!='*' && i!='\33' && i!='.')) i=getchar();
 -	if (i == '\33')
 -		{ setscroll(); recalc(); drawscreen(); nosignal=0; /* enable signals */ return; }
 -	isub = i - 'a';		j=0;
 -	if (iven[isub]==OSCROLL) if (scrollname[ivenarg[isub]][0]==0)
 -		{ j=1; cnsitm(); }	/* can't sell unidentified item */
 -	if (iven[isub]==OPOTION) if (potionname[ivenarg[isub]][0]==0)
 -		{ j=1; cnsitm(); }	/* can't sell unidentified item */
 -	if (!j)
 -	  if (i=='*') { clear(); qshowstr(); otradhead(); }
 -	else  if (iven[isub]==0)  lprintf("\nYou don't have item %c!",isub+'a');
 -	else
 -		{
 -		for (j=0; j<maxitm; j++)
 -		  if ((itm[j].obj == iven[isub]) || (iven[isub] == ODIAMOND) || (iven[isub] == ORUBY) || (iven[isub] == OEMERALD) || (iven[isub] == OSAPPHIRE))
 -			{
 -			srcount=0;  show3(isub);	/* show what the item was */
 -			if ((iven[isub] == ODIAMOND) || (iven[isub] == ORUBY)
 -				|| (iven[isub] == OEMERALD) || (iven[isub] == OSAPPHIRE))
 -				value = 20*ivenarg[isub];
 -			else
 -			if ((itm[j].obj == OSCROLL) || (itm[j].obj == OPOTION))  value = 2*itm[j+ivenarg[isub]].price;
 -			else
 -				{
 -				izarg=ivenarg[isub];  value = itm[j].price;	/* appreciate if a +n object */
 -				if (izarg >= 0) value *= 2;
 -				while ((izarg-- > 0) && ((value=14*(67+value)/10) < 500000));
 -				}
 -			lprintf("\nItem (%c) is worth %d gold pieces to us.  Do you want to sell it? ",i,(long)value);
 -			yrepcount=0;
 -			if (getyn()=='y')
 -				{
 -				lprcat("yes\n"); c[GOLD]+=value;
 -				if (c[WEAR] == isub) c[WEAR] = -1;
 -				if (c[WIELD] == isub) c[WIELD] = -1;
 -				if (c[SHIELD] == isub) c[SHIELD] = -1;
 -				adjustcvalues(iven[isub],ivenarg[isub]);
 -				iven[isub]=0;
 -				}
 -			else lprcat("no thanks.\n");
 -			j = maxitm+100;	/* get out of the inner loop */
 -			}
 -		if (j <= maxitm+2) lprcat("\nSo sorry, but we are not authorized to accept that item.");
 -		}
 -	}
 -  }
 +{
 +    int i,j,value,isub,izarg;
 +    dnditm = dndcount = 0;
 +    nosignal = 1; /* disable signals */
 +    resetscroll();
 +    otradhead();
 +    while (1)
 +    {
 +        lprcat("\nWhat item do you want to sell to us [");
 +        standout("*");
 +        lprcat(" for list, or ");
 +        standout("escape");
 +        lprcat("] ? ");
 +        i=0;
 +        while (i>'z' || (i<'a' && i!='*' && i!='\33' && i!='.')) i=getchar();
 +        if (i == '\33') {
 +            setscroll();
 +            recalc();
 +            drawscreen();
 +            nosignal=0; /* enable signals */
 +            return;
 +        }
 +        isub = i - 'a';
 +        j=0;
 +        if (iven[isub]==OSCROLL)
 +            if (! IS_IDENTIFIED(scrollname[ivenarg[isub]].flag)) {
 +                /* can't sell unidentified item */
 +                j=1;
 +                cnsitm();
 +            }
 +        if (iven[isub]==OPOTION)
 +            if (! IS_IDENTIFIED(potionname[ivenarg[isub]].flag)) {
 +                /* can't sell unidentified item */
 +                j=1;
 +                cnsitm();
 +            }
 +        if (!j)
 +            if (i=='*') {
 +                clear();
 +                qshowstr();
 +                otradhead();
 +            }
 +            else
 +                if (iven[isub]==0)
 +                    lprintf("\nYou don't have item %c!",isub+'a');
 +                else {
 +                    for (j=0; j<maxitm; j++)
 +                        if ((itm[j].obj == iven[isub]) ||
 +                                (iven[isub] == ODIAMOND) ||
 +                                (iven[isub] == ORUBY) ||
 +                                (iven[isub] == OEMERALD) ||
 +                                (iven[isub] == OSAPPHIRE))
 +                        {
 +                            srcount=0;
 +                            show3(isub);    /* show what the item was */
 +                            if ((iven[isub] == ODIAMOND) ||
 +                                    (iven[isub] == ORUBY) ||
 +                                    (iven[isub] == OEMERALD) ||
 +                                    (iven[isub] == OSAPPHIRE))
 +                                value = 20*ivenarg[isub];
 +                            else
 +                                if ((itm[j].obj == OSCROLL) ||
 +                                        (itm[j].obj == OPOTION))
 +                                    value = 2*itm[j+ivenarg[isub]].price;
 +                                else {
 +                                    izarg=ivenarg[isub];
 +                                    value = itm[j].price;   /* appreciate if a +n object */
 +                                    if (izarg >= 0)
 +                                        value *= 2;
 +                                    while ((izarg-- > 0) &&
 +                                            ((value=14*(67+value)/10) < 500000));
 +                                }
 +            lprintf("\nItem (%c) is worth %d gold pieces to us.  Do you want to sell it? ",i,(long)value);
 +                            yrepcount=0;
 +                            if (getyn()=='y') {
 +                                lprcat("yes\n");
 +                                c[GOLD]+=value;
 +                                if (c[WEAR] == isub)
 +                                    c[WEAR] = -1;
 +                                if (c[WIELD] == isub)
 +                                    c[WIELD] = -1;
 +                                if (c[SHIELD] == isub)
 +                                    c[SHIELD] = -1;
 +                                adjustcvalues(iven[isub],ivenarg[isub]);
 +                                iven[isub]=0;
 +                            }
 +                            else
 +                                lprcat("no thanks.\n");
 +                            j = maxitm+100; /* get out of the inner loop */
 +                        }
 +                    if (j <= maxitm+2) lprcat("\nSo sorry, but we are not authorized to accept that item.");
 +                }
 +    }
 +}
  
  cnsitm()
  	{ lprcat("\nSorry, we can't accept unidentified objects."); }
 
 --kfjH4zxOES6UT95V--

From: Ulrich Spoerlein <uspoerlein@gmail.com>
To: bug-followup@FreeBSD.org, ino-news@spotteswoode.dnsalias.org
Cc:  
Subject: Re: ports/127728: ports/games/freebsd-games doesn't build, and
 larn(6) segfaults!
Date: Tue, 21 Jul 2009 19:48:59 +0200

 --CE+1k2dSO48ffgeK
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 Hi Clemens,
 
 please try the attached patch for the freebsd-games port and see if it
 fixes the most pressing larn segfaults on 8.0-CURRENT.
 
 It still segfaults on exit for me, but fixing this with patches upon
 patches is not the right way.
 
 As for atc, I cannot reproduce this here. Is this still a valid problem?
 
 Cheers,
 Uli
 
 --CE+1k2dSO48ffgeK
 Content-Type: text/x-diff; charset=us-ascii
 Content-Disposition: attachment; filename="larn.diff"
 
 diff -r f2064db6b76c larn/Makefile
 --- a/larn/Makefile	Tue Jul 21 17:26:23 2009 +0200
 +++ b/larn/Makefile	Tue Jul 21 19:07:29 2009 +0200
 @@ -54,7 +54,7 @@
  
  PROG=	larn
  MAN=	larn.6
 -CFLAGS+=-DPOSIX -DVER=12 -DSUBVER=0 -DNONAP -DUIDSCORE -DNOVARARGS
 +CFLAGS+=-DPOSIX -DVER=12 -DSUBVER=0 -DNONAP -DUIDSCORE
  SRCS=	main.c object.c create.c tok.c display.c global.c data.c io.c \
  	monster.c store.c diag.c help.c config.c nap.c bill.c scores.c \
  	signal.c moreobj.c movem.c regen.c fortune.c savelev.c
 diff -r f2064db6b76c larn/data.c
 --- a/larn/data.c	Tue Jul 21 17:26:23 2009 +0200
 +++ b/larn/data.c	Tue Jul 21 19:07:29 2009 +0200
 @@ -299,7 +299,7 @@
  
  /*	name array for scrolls		*/
  
 -char *scrollname[] = {
 +char *scrollname[32] = {
  "\0enchant armor",
  "\0enchant weapon",
  "\0enlightenment",
 @@ -327,11 +327,15 @@
  "\0 ",
  "\0 ",
  "\0 ",
 +"\0 ",
 +"\0 ",
 +"\0 ",
 +"\0 ",
  "\0 "
   };
  
  /*	name array for magic potions	*/
 -char *potionname[] = {
 +char *potionname[32] = {
  "\0sleep",
  "\0healing",
  "\0raise level",
 @@ -363,9 +367,6 @@
  "\0 ",
  "\0 ",
  "\0 ",
 -"\0 ",
 -"\0 ",
 -"\0 ",
  "\0 "
   };
  
 diff -r f2064db6b76c larn/global.c
 --- a/larn/global.c	Tue Jul 21 17:26:23 2009 +0200
 +++ b/larn/global.c	Tue Jul 21 19:07:29 2009 +0200
 @@ -27,7 +27,7 @@
  extern char lastmonst[],*what[],*who[];
  extern char winner[];
  extern char logname[],monstlevel[];
 -extern char sciv[SCORESIZE+1][26][2],*potionname[],*scrollname[];
 +extern char sciv[SCORESIZE+1][26][2],*potionname[][32],*scrollname[][32];
  /*
  	***********
  	RAISE LEVEL
 diff -r f2064db6b76c larn/header.h
 --- a/larn/header.h	Tue Jul 21 17:26:23 2009 +0200
 +++ b/larn/header.h	Tue Jul 21 19:07:29 2009 +0200
 @@ -341,9 +341,9 @@
  extern char *lpnt,moved[MAXX][MAXY],mitem[MAXX][MAXY],monstlevel[];
  extern char monstnamelist[],nch[],ndgg[],nlpts[],nomove,nosignal,nowelcome;
  extern char nplt[],nsw[],*objectname[];
 -extern char objnamelist[],optsfile[],*potionname[],playerids[],potprob[];
 +extern char objnamelist[],optsfile[],*potionname[][32],playerids[],potprob[];
  extern char predostuff,psname[],restorflag,savefilename[],scorefile[],scprob[];
 -extern char screen[MAXX][MAXY],*scrollname[],sex,*spelcode[],*speldescript[];
 +extern char screen[MAXX][MAXY],*scrollname[][32],sex,*spelcode[],*speldescript[];
  extern char spelknow[],*spelname[],*spelmes[],spelweird[MAXMONST+8][SPNUM];
  extern char splev[],stealth[MAXX][MAXY],to_lower[],to_upper[],wizard;
  extern short diroffx[],diroffy[],hitflag,hit2flag,hit3flag,hitp[MAXX][MAXY];
 diff -r f2064db6b76c larn/io.c
 --- a/larn/io.c	Tue Jul 21 17:26:23 2009 +0200
 +++ b/larn/io.c	Tue Jul 21 19:07:29 2009 +0200
 @@ -92,7 +92,7 @@
  #endif /* not SYSV */
  
  #ifndef NOVARARGS	/* if we have varargs */
 -#include <varargs.h>
 +#include <stdarg.h>
  #else /* NOVARARGS *//* if we don't have varargs */
  typedef char *va_list;
  #define va_dcl int va_alist;
 @@ -205,17 +205,14 @@
  	}
  #else /* lint */
  /*VARARGS*/
 -lprintf(va_alist)
 -va_dcl
 +lprintf(const char *fmt, ...)
      {
  	va_list ap;	/* pointer for variable argument list */
 -	char *fmt;
  	char *outb,*tmpb;
  	long wide,left,cont,n;		/* data for lprintf	*/
  	char db[12];			/* %d buffer in lprintf	*/
  
 -	va_start(ap);	/* initialize the var args pointer */
 -	fmt = va_arg(ap, char *);	/* pointer to format string */
 +	va_start(ap, fmt);	/* initialize the var args pointer */
  	if (lpnt >= lpend) lflush();
  	outb = lpnt;
  	for ( ; ; )
 
 --CE+1k2dSO48ffgeK--

From: Ulrich =?utf-8?B?U3DDtnJsZWlu?= <uqs@spoerlein.net>
To: bug-followup@FreeBSD.org, ino-news@spotteswoode.dnsalias.org
Cc:  
Subject: Re: ports/127728: ports/games/freebsd-games doesn't build, and
 larn(6) segfaults!
Date: Tue, 21 Jul 2009 20:00:13 +0200

 --EeQfGwPcQSOJBaQU
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 Sigh, wrong file. Try this one ...
 
 --EeQfGwPcQSOJBaQU
 Content-Type: text/x-diff; charset=us-ascii
 Content-Disposition: attachment; filename="larn.diff"
 
 Index: Makefile
 ===================================================================
 RCS file: /tank/ncvs/ports/games/freebsd-games/Makefile,v
 retrieving revision 1.20
 diff -u -p -r1.20 Makefile
 --- Makefile	2 Mar 2009 01:27:11 -0000	1.20
 +++ Makefile	21 Jul 2009 17:59:56 -0000
 @@ -7,7 +7,7 @@
  
  PORTNAME=	freebsd-games
  PORTVERSION=	5.1.1
 -PORTREVISION=	7
 +PORTREVISION=	8
  CATEGORIES=	games
  MASTER_SITES=	${MASTER_SITE_LOCAL}
  MASTER_SITE_SUBDIR=markm
 Index: files/patch-larn_Makefile
 ===================================================================
 RCS file: /tank/ncvs/ports/games/freebsd-games/files/patch-larn_Makefile,v
 retrieving revision 1.1
 diff -u -p -r1.1 patch-larn_Makefile
 --- files/patch-larn_Makefile	23 Mar 2007 23:02:33 -0000	1.1
 +++ files/patch-larn_Makefile	21 Jul 2009 17:59:56 -0000
 @@ -1,10 +1,18 @@
 -Index: larn/Makefile
 -@@ -54,7 +54,7 @@
 +--- larn/Makefile.orig	2003-11-11 00:47:00.000000000 +0100
 ++++ larn/Makefile	2009-07-21 19:08:50.000000000 +0200
 +@@ -54,12 +54,12 @@
   
   PROG=	larn
   MAN=	larn.6
  -CFLAGS+=-DBSD -DVER=12 -DSUBVER=0 -DNONAP -DUIDSCORE -fwritable-strings -DNOVARARGS
 -+CFLAGS+=-DPOSIX -DVER=12 -DSUBVER=0 -DNONAP -DUIDSCORE -DNOVARARGS
 ++CFLAGS+=-DPOSIX -DVER=12 -DSUBVER=0 -DNONAP -DUIDSCORE
   SRCS=	main.c object.c create.c tok.c display.c global.c data.c io.c \
   	monster.c store.c diag.c help.c config.c nap.c bill.c scores.c \
   	signal.c moreobj.c movem.c regen.c fortune.c savelev.c
 +-DPADD=	${LIBTERMCAP} ${LIBCOMPAT}
 +-LDADD=	-ltermcap -lcompat
 ++DPADD=	${LIBTERMCAP} 
 ++LDADD=	-ltermcap 
 + FILES=	larnmaze larnopts larn.help
 + FILESDIR=	${SHAREDIR}/games/larn
 + 
 Index: files/patch-larn_data.c
 ===================================================================
 RCS file: files/patch-larn_data.c
 diff -N files/patch-larn_data.c
 --- /dev/null	1 Jan 1970 00:00:00 -0000
 +++ files/patch-larn_data.c	21 Jul 2009 17:59:56 -0000
 @@ -0,0 +1,38 @@
 +--- larn/data.c.orig	1999-11-30 04:48:59.000000000 +0100
 ++++ larn/data.c	2009-07-21 19:08:50.000000000 +0200
 +@@ -299,7 +299,7 @@
 + 
 + /*	name array for scrolls		*/
 + 
 +-char *scrollname[] = {
 ++char *scrollname[32] = {
 + "\0enchant armor",
 + "\0enchant weapon",
 + "\0enlightenment",
 +@@ -327,11 +327,15 @@
 + "\0 ",
 + "\0 ",
 + "\0 ",
 ++"\0 ",
 ++"\0 ",
 ++"\0 ",
 ++"\0 ",
 + "\0 "
 +  };
 + 
 + /*	name array for magic potions	*/
 +-char *potionname[] = {
 ++char *potionname[32] = {
 + "\0sleep",
 + "\0healing",
 + "\0raise level",
 +@@ -363,9 +367,6 @@
 + "\0 ",
 + "\0 ",
 + "\0 ",
 +-"\0 ",
 +-"\0 ",
 +-"\0 ",
 + "\0 "
 +  };
 + 
 Index: files/patch-larn_global.c
 ===================================================================
 RCS file: files/patch-larn_global.c
 diff -N files/patch-larn_global.c
 --- /dev/null	1 Jan 1970 00:00:00 -0000
 +++ files/patch-larn_global.c	21 Jul 2009 17:59:56 -0000
 @@ -0,0 +1,11 @@
 +--- larn/global.c.orig	2002-05-08 22:39:10.000000000 +0200
 ++++ larn/global.c	2009-07-21 19:08:50.000000000 +0200
 +@@ -27,7 +27,7 @@
 + extern char lastmonst[],*what[],*who[];
 + extern char winner[];
 + extern char logname[],monstlevel[];
 +-extern char sciv[SCORESIZE+1][26][2],*potionname[],*scrollname[];
 ++extern char sciv[SCORESIZE+1][26][2],*potionname[][32],*scrollname[][32];
 + /*
 + 	***********
 + 	RAISE LEVEL
 Index: files/patch-larn_header.h
 ===================================================================
 RCS file: /tank/ncvs/ports/games/freebsd-games/files/patch-larn_header.h,v
 retrieving revision 1.1
 diff -u -p -r1.1 patch-larn_header.h
 --- files/patch-larn_header.h	23 Mar 2007 23:02:33 -0000	1.1
 +++ files/patch-larn_header.h	21 Jul 2009 17:59:56 -0000
 @@ -1,4 +1,5 @@
 -Index: larn/header.h
 +--- larn/header.h.orig	2002-05-08 22:39:10.000000000 +0200
 ++++ larn/header.h	2009-07-21 19:08:50.000000000 +0200
  @@ -326,7 +326,6 @@
   #define DEMONLORD 57
   #define DEMONPRINCE 64
 @@ -7,7 +8,19 @@ Index: larn/header.h
   #define BUFBIG	4096			/* size of the output buffer */
   #define MAXIBUF	4096			/* size of the input buffer */
   #define LOGNAMESIZE 40			/* max size of the players name */
 -@@ -359,7 +359,7 @@
 +@@ -342,9 +341,9 @@
 + extern char *lpnt,moved[MAXX][MAXY],mitem[MAXX][MAXY],monstlevel[];
 + extern char monstnamelist[],nch[],ndgg[],nlpts[],nomove,nosignal,nowelcome;
 + extern char nplt[],nsw[],*objectname[];
 +-extern char objnamelist[],optsfile[],*potionname[],playerids[],potprob[];
 ++extern char objnamelist[],optsfile[],*potionname[][32],playerids[],potprob[];
 + extern char predostuff,psname[],restorflag,savefilename[],scorefile[],scprob[];
 +-extern char screen[MAXX][MAXY],*scrollname[],sex,*spelcode[],*speldescript[];
 ++extern char screen[MAXX][MAXY],*scrollname[][32],sex,*spelcode[],*speldescript[];
 + extern char spelknow[],*spelname[],*spelmes[],spelweird[MAXMONST+8][SPNUM];
 + extern char splev[],stealth[MAXX][MAXY],to_lower[],to_upper[],wizard;
 + extern short diroffx[],diroffy[],hitflag,hit2flag,hit3flag,hitp[MAXX][MAXY];
 +@@ -360,7 +359,7 @@
   
   char *fortune(),*lgetw(),*lgetl();
   char *tmcapcnv();
 Index: files/patch-larn_io.c
 ===================================================================
 RCS file: /tank/ncvs/ports/games/freebsd-games/files/patch-larn_io.c,v
 retrieving revision 1.1
 diff -u -p -r1.1 patch-larn_io.c
 --- files/patch-larn_io.c	23 Mar 2007 23:02:33 -0000	1.1
 +++ files/patch-larn_io.c	21 Jul 2009 17:59:56 -0000
 @@ -1,4 +1,5 @@
 -Index: larn/io.c
 +--- larn/io.c.orig	2002-05-08 22:39:10.000000000 +0200
 ++++ larn/io.c	2009-07-21 19:08:50.000000000 +0200
  @@ -24,7 +24,7 @@
    *	FILE INPUT ROUTINES
    *
 @@ -26,7 +27,36 @@ Index: larn/io.c
   #else /* not SYSV */
   
   #ifndef BSD
 -@@ -345,7 +356,7 @@
 +@@ -81,7 +92,7 @@
 + #endif /* not SYSV */
 + 
 + #ifndef NOVARARGS	/* if we have varargs */
 +-#include <varargs.h>
 ++#include <stdarg.h>
 + #else /* NOVARARGS *//* if we don't have varargs */
 + typedef char *va_list;
 + #define va_dcl int va_alist;
 +@@ -194,17 +205,14 @@
 + 	}
 + #else /* lint */
 + /*VARARGS*/
 +-lprintf(va_alist)
 +-va_dcl
 ++lprintf(const char *fmt, ...)
 +     {
 + 	va_list ap;	/* pointer for variable argument list */
 +-	char *fmt;
 + 	char *outb,*tmpb;
 + 	long wide,left,cont,n;		/* data for lprintf	*/
 + 	char db[12];			/* %d buffer in lprintf	*/
 + 
 +-	va_start(ap);	/* initialize the var args pointer */
 +-	fmt = va_arg(ap, char *);	/* pointer to format string */
 ++	va_start(ap, fmt);	/* initialize the var args pointer */
 + 	if (lpnt >= lpend) lflush();
 + 	outb = lpnt;
 + 	for ( ; ; )
 +@@ -345,7 +353,7 @@
       }
   
   /*
 @@ -35,7 +65,7 @@ Index: larn/io.c
    *
    *		+---------+---------+---------+---------+
    *		|	high  |			|		  |	  low	|
 -@@ -357,7 +368,7 @@
 +@@ -357,7 +365,7 @@
    *	The save order is low order first, to high order (4 bytes total)
    *	Returns the int read
    */
 
 --EeQfGwPcQSOJBaQU--

From: clemens fischer <ino-news@spotteswoode.dnsalias.org>
To: Ulrich Spoerlein <uspoerlein@gmail.com>
Cc: bug-followup@FreeBSD.org
Subject: Re: ports/127728: ports/games/freebsd-games doesn't build, and
	larn(6) segfaults!
Date: Tue, 21 Jul 2009 20:08:28 +0200

 > Ulrich Spoerlein:
 
 > Hi Clemens,
 > 
 > please try the attached patch for the freebsd-games port and see if it
 > fixes the most pressing larn segfaults on 8.0-CURRENT.
 >
 > It still segfaults on exit for me, but fixing this with patches upon
 > patches is not the right way.
 
 Well, the problem seemed to be the way gcc stores strings in
 non-writable memory, so I replaced that part with a proper record
 structure.  your patch is just another patch, so why is it any better
 than mine?
 
 Also, no segfault is acceptable before scores are written to disk.
 
 > As for atc, I cannot reproduce this here. Is this still a valid
 > problem?
 
 Sorry, I can't help, because I don't have a working freebsd
 installation ATM.
 
 
 regards, clemens fischer

From: Ulrich =?utf-8?B?U3DDtnJsZWlu?= <uqs@spoerlein.net>
To: bug-followup@FreeBSD.org, ino-news@spotteswoode.dnsalias.org
Cc: miwi@FreeBSD.org
Subject: Re: ports/127728: ports/games/bsdgames doesn't build, and larn(6)
 segfaults!
Date: Mon, 21 Dec 2009 11:27:32 +0100

 Please close this PR, it no longer applies, the underlying codebase has
 changed and builds and works mostly fine.
 
 Thanks!
 Uli
State-Changed-From-To: open->closed 
State-Changed-By: linimon 
State-Changed-When: Mon Dec 21 10:43:45 UTC 2009 
State-Changed-Why:  
Apparently OBE. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=127728 
>Unformatted:
