# HG changeset patch # User elwin # Date 1290706109 0 # Node ID 34d7a614855ef089b62dc41805d52e05e84a22a3 # Parent 2128c7dc8a400686fb31035586bd3c6e5fbcfc51 srogue: add support for SAVEDIR diff -r 2128c7dc8a40 -r 34d7a614855e srogue/global.c --- 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 */ diff -r 2128c7dc8a40 -r 34d7a614855e srogue/main.c --- 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()); diff -r 2128c7dc8a40 -r 34d7a614855e srogue/options.c --- 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; +} diff -r 2128c7dc8a40 -r 34d7a614855e srogue/rogue.ext --- 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[]; diff -r 2128c7dc8a40 -r 34d7a614855e srogue/save.c --- 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;