Ted Unangst wrote:
> Theo Buehler wrote:
> > In its current form, tetris is a setgid program and needs a whopping
> >
> > pledge("stdio rpath wpath cpath flock getpw id tty")
> >
> > throughout its lifetime because of the score file in /var/games.
> >
> > As discussed with Theo off-list, this is risk-only. Thus, drop the
> > score file support, lose the setgid bit and make tetris a much more
> > reasonable pledge("stdio rpath tty") program for relaxed game play.
>
> No way! this is critical functionality. :)
>
> Can you just change it to save the scores in HOME/.tetrisscores?
The score code still makes a weak attempt to save unique users, which i may
relax, but this should let you get by with just basic stdio stuff.
Index: Makefile
===================================================================
RCS file: /cvs/src/games/tetris/Makefile,v
retrieving revision 1.7
diff -u -p -r1.7 Makefile
--- Makefile 31 May 2002 03:46:35 -0000 1.7
+++ Makefile 17 Nov 2015 05:35:40 -0000
@@ -5,14 +5,5 @@ SRCS= input.c screen.c shapes.c scores.c
MAN= tetris.6
DPADD= ${LIBCURSES}
LDADD= -lcurses
-BINMODE=2555
-
-beforeinstall:
- @if [ ! -f ${DESTDIR}/var/games/tetris.scores ]; then \
- ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m 664 \
- /dev/null ${DESTDIR}/var/games/tetris.scores ; \
- else \
- true ; \
- fi
.include <bsd.prog.mk>
Index: pathnames.h
===================================================================
RCS file: pathnames.h
diff -N pathnames.h
--- pathnames.h 3 Jun 2003 03:01:41 -0000 1.3
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,38 +0,0 @@
-/* $OpenBSD: pathnames.h,v 1.3 2003/06/03 03:01:41 millert Exp $ */
-/* $NetBSD: pathnames.h,v 1.2 1995/04/22 07:42:37 cgd Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek and Darren F. Provine.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)pathnames.h 8.1 (Berkeley) 5/31/93
- */
-
-#define _PATH_SCOREFILE "/var/games/tetris.scores"
Index: scores.c
===================================================================
RCS file: /cvs/src/games/tetris/scores.c,v
retrieving revision 1.12
diff -u -p -r1.12 scores.c
--- scores.c 16 Nov 2014 04:49:49 -0000 1.12
+++ scores.c 17 Nov 2015 05:43:50 -0000
@@ -49,7 +49,6 @@
#include <err.h>
#include <fcntl.h>
#include <limits.h>
-#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -57,7 +56,6 @@
#include <term.h>
#include <unistd.h>
-#include "pathnames.h"
#include "screen.h"
#include "scores.h"
#include "tetris.h"
@@ -98,50 +96,44 @@ getscores(FILE **fpp)
{
int sd, mint, lck, mask, i;
char *mstr, *human;
+ char scorepath[PATH_MAX];
FILE *sf;
if (fpp != NULL) {
- mint = O_RDWR | O_CREAT;
+ mint = O_RDWR | O_CREAT | O_EXLOCK;
mstr = "r+";
human = "read/write";
- lck = LOCK_EX;
+ *fpp = NULL;
} else {
- mint = O_RDONLY;
+ mint = O_RDONLY | O_EXLOCK;
mstr = "r";
human = "reading";
- lck = LOCK_SH;
}
- setegid(egid);
+ if (!getenv("HOME"))
+ return;
mask = umask(S_IWOTH);
- sd = open(_PATH_SCOREFILE, mint, 0666);
+ snprintf(scorepath, sizeof(scorepath), "%s/%s", getenv("HOME"),
".tetris.scores");
+ sd = open(scorepath, mint, 0666);
(void)umask(mask);
- setegid(gid);
if (sd < 0) {
if (fpp == NULL) {
nscores = 0;
return;
}
- err(1, "cannot open %s for %s", _PATH_SCOREFILE, human);
+ err(1, "cannot open %s for %s", scorepath, human);
}
setegid(egid);
if ((sf = fdopen(sd, mstr)) == NULL)
- err(1, "cannot fdopen %s for %s", _PATH_SCOREFILE, human);
+ err(1, "cannot fdopen %s for %s", scorepath, human);
setegid(gid);
- /*
- * Grab a lock.
- */
- if (flock(sd, lck))
- warn("warning: score file %s cannot be locked",
- _PATH_SCOREFILE);
-
nscores = fread(scores, sizeof(scores[0]), MAXHISCORES, sf);
if (ferror(sf))
- err(1, "error reading %s", _PATH_SCOREFILE);
+ err(1, "error reading %s", scorepath);
for (i = 0; i < nscores; i++)
if (scores[i].hs_level < MINLEVEL ||
scores[i].hs_level > MAXLEVEL)
- errx(1, "scorefile %s corrupt", _PATH_SCOREFILE);
+ errx(1, "scorefile %s corrupt", scorepath);
if (fpp)
*fpp = sf;
@@ -204,8 +196,8 @@ savescore(int level)
rewind(sf);
if (fwrite(scores, sizeof(*sp), nscores, sf) != nscores ||
fflush(sf) == EOF)
- warnx("error writing %s: %s\n\t-- %s",
- _PATH_SCOREFILE, strerror(errno),
+ warnx("error writing scorefile: %s\n\t-- %s",
+ strerror(errno),
"high scores may be damaged");
}
(void)fclose(sf); /* releases lock */
@@ -219,17 +211,14 @@ static char *
thisuser(void)
{
const char *p;
- struct passwd *pw;
static char u[sizeof(scores[0].hs_name)];
if (u[0])
return (u);
p = getlogin();
if (p == NULL || *p == '\0') {
- pw = getpwuid(getuid());
- if (pw != NULL)
- p = pw->pw_name;
- else
+ p = getenv("USER");
+ if (p == NULL || *p == '\0')
p = " ???";
}
strlcpy(u, p, sizeof(u));
@@ -315,7 +304,6 @@ checkscores(struct highscore *hs, int nu
* - High score on this level.
*/
if ((pu->times < MAXSCORES &&
- getpwnam(sp->hs_name) != NULL &&
sp->hs_time + EXPIRATION >= now) ||
levelfound[sp->hs_level] == 0)
pu->times++;