changeset 37:34d7a614855e

srogue: add support for SAVEDIR
author elwin
date Thu, 25 Nov 2010 17:28:29 +0000
parents 2128c7dc8a40
children 8a9525231fb6
files srogue/global.c srogue/main.c srogue/options.c srogue/rogue.ext srogue/save.c
diffstat 5 files changed, 91 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/srogue/global.c	Thu Nov 25 12:21:41 2010 +0000
+++ b/srogue/global.c	Thu Nov 25 17:28:29 2010 +0000
@@ -86,6 +86,7 @@
 bool amulet = FALSE;		/* He found the amulet */
 bool in_shell = FALSE;		/* True if executing a shell */
 bool nochange = FALSE;		/* true if last stat same as now */
+bool use_savedir = FALSE;	/* true if using system savefiles */
 
 bool s_know[MAXSCROLLS];		/* Does he know about a scroll */
 bool p_know[MAXPOTIONS];		/* Does he know about a potion */
--- a/srogue/main.c	Thu Nov 25 12:21:41 2010 +0000
+++ b/srogue/main.c	Thu Nov 25 17:28:29 2010 +0000
@@ -37,6 +37,9 @@
 
 #include "rogue.ext"
 
+#define SCOREFILE "/usr/local/games/roguelike/srogue.scr"
+#define SAVEDIR "/usr/local/games/roguelike/sroguesave/"
+
 struct termios terminal;
 
 main(argc, argv, envp)
@@ -71,12 +74,17 @@
 	playgid = getgid();
 
 	/* check for print-score option */
+#ifdef SCOREFILE
+	strncpy(scorefile, SCOREFILE, LINLEN);
+	scorefile[LINLEN - 1] = '\0';
+#else
 
 	strcpy(scorefile, homedir);
 
 	if (*scorefile)
 		strcat(scorefile,"/");
 	strcat(scorefile, "srogue.scr");
+#endif
 
 	if(argc >= 2 && strcmp(argv[1], "-s") == 0)
 	{
@@ -105,6 +113,20 @@
 	time(&now);
 	lowtime = (int) now;
 
+#ifdef SAVEDIR
+	if (argc >= 3 && !strcmp(argv[1], "-n")) {
+		strncpy(whoami, argv[2], LINLEN);
+		whoami[LINLEN - 1] = '\0';
+		use_savedir = TRUE;
+		if (snprintf(file_name, LINLEN, "%s%d-%.10s.srsav", SAVEDIR, 
+			playuid, whoami) >= LINLEN) {
+			/* Just in case it doesn't fit */
+			strcpy(file_name, "srogue.save");
+			use_savedir = FALSE;
+		}
+	}
+#endif
+
 	/* get home and options from environment */
 
 	if ((env = getenv("HOME")) != NULL)
@@ -120,13 +142,15 @@
         if ((strlen(home) > 0) && (home[strlen(home)-1] != '/'))
 		strcat(home, "/");
 
-	strcpy(file_name, home);
-	strcat(file_name, "srogue.sav");
+	if (!use_savedir) {
+		strcpy(file_name, home);
+		strcat(file_name, "srogue.sav");
+        }
 
 	if ((env = getenv("ROGUEOPTS")) != NULL)
 		parse_opts(env);
 
-	if (env == NULL || whoami[0] == '\0')
+	if (!use_savedir && (env == NULL || whoami[0] == '\0'))
 	{
 		if((pw = getpwuid(playuid)) == NULL)
 		{
@@ -140,10 +164,20 @@
 	if (env == NULL || fruit[0] == '\0')
 		strcpy(fruit, "juicy-fruit");
 
-	if (argc == 2)
+	if (use_savedir)
+	{
+		/* restore() won't return if the restore succeeded.  If
+		 * file_name doesn't exist, it will return TRUE. In that 
+		 * case, start a new game. */
+		if (!restore(file_name, envp))
+			exit(1);
+	}
+	else if (argc == 2)
 		if(!restore(argv[1], envp)) /* NOTE: NEVER RETURNS */
 			exit(1);
 
+	/* START NEW GAME */
+
 	dnum = (wizard && getenv("SEED") != NULL ?
 		atoi(getenv("SEED")) : lowtime + getpid());
 
--- a/srogue/options.c	Thu Nov 25 12:21:41 2010 +0000
+++ b/srogue/options.c	Thu Nov 25 17:28:29 2010 +0000
@@ -185,6 +185,9 @@
 			continue;
 		len = sp - str;
 		for (op = optlist; op < &optlist[NUM_OPTS]; op++) {
+			/* For security, some options can't be changed. */
+			if (!allowchange(op))
+				continue;
 			if (EQSTR(str, op->o_name, len)) {
 				reg char *start;
 	
@@ -228,3 +231,14 @@
 	}
 	*s1 = '\0';
 }
+
+int allowchange(OPTION *opt)
+{
+	if (!use_savedir)
+		return 1;
+	if (!strcmp(opt->o_name, "name"))
+		return 0;
+	if (!strcmp(opt->o_name, "file"))
+		return 0;
+	return 1;
+}
--- a/srogue/rogue.ext	Thu Nov 25 12:21:41 2010 +0000
+++ b/srogue/rogue.ext	Thu Nov 25 17:28:29 2010 +0000
@@ -20,7 +20,7 @@
 EXTINT prntfile(), unconfuse(), sapem();
 EXTINT noteth(), notregen(), notinvinc(), unsee(), nohaste(), npch();
 EXTBOOL running, nochange, after, inwhgt, isfight, firstmove, nlmove;
-EXTBOOL wizard, waswizard, in_shell, amulet, door_stop, playing;
+EXTBOOL wizard, waswizard, in_shell, amulet, door_stop, playing, use_savedir;
 EXTBOOL notify, ws_know[], p_know[], s_know[], r_know[], inpool;
 EXTCHAR home[], file_name[], whoami[], fruit[], curpurch[], scorefile[];
 EXTCHAR *r_stones[], *p_colors[], *s_names[], *ws_type[], *ws_made[];
--- a/srogue/save.c	Thu Nov 25 12:21:41 2010 +0000
+++ b/srogue/save.c	Thu Nov 25 17:28:29 2010 +0000
@@ -136,8 +136,11 @@
 	FILE *savef;
 
 	ignore();
-	setuid(playuid);
-	setgid(playgid);
+	if (!use_savedir)
+	{
+		setuid(playuid);
+		setgid(playgid);
+	}
 	umask(022);
 
 	if (file_name[0] != '\0') {
@@ -209,8 +212,12 @@
 	int slines, scols;
 
 	if ((inf = open(file, O_RDONLY)) < 0) {
-		printf("Cannot read save game %s\n",file);
-		return FALSE;
+		if (use_savedir && errno == ENOENT)
+			return TRUE;
+		else {
+			printf("Cannot read save game %s\n",file);
+			return FALSE;
+		}
 	}
 
 	encread(buf, strlen(version) + 1, inf);
@@ -297,23 +304,36 @@
 	{
 #ifndef __DJGPP__
 			endwin();
-			while((pid = fork()) < 0)
-				sleep(1);
-
-			/* set id to unlink file */
-			if(pid == 0)
+			if (!use_savedir)
 			{
-				setuid(playuid);
-				setgid(playgid);
-				unlink(file);
-				exit(0);
+				while((pid = fork()) < 0)
+					sleep(1);
+
+				/* set id to unlink file */
+				if(pid == 0)
+				{
+					setuid(playuid);
+					setgid(playgid);
+					unlink(file);
+					exit(0);
+				}
+				/* wait for unlink to finish */
+				else
+				{
+					while(wait(&ret_status) != pid)
+						continue;
+					if (ret_status < 0)
+					{
+						printf("Cannot unlink file\n");
+						return FALSE;
+					}
+				}
 			}
-			/* wait for unlink to finish */
 			else
 			{
-				while(wait(&ret_status) != pid)
-					continue;
-				if (ret_status < 0)
+				/* Don't drop privileges, they're needed
+				 * for the unlink. */
+				if (unlink(file) < 0)
 				{
 					printf("Cannot unlink file\n");
 					return FALSE;