[BACK]Return to save.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / rogue4

Annotation of early-roguelike/rogue4/save.c, Revision 1.1

1.1     ! rubenllo    1: /*
        !             2:  * save and restore routines
        !             3:  *
        !             4:  * @(#)save.c  4.15 (Berkeley) 5/10/82
        !             5:  *
        !             6:  * Rogue: Exploring the Dungeons of Doom
        !             7:  * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
        !             8:  * All rights reserved.
        !             9:  *
        !            10:  * See the file LICENSE.TXT for full copyright and licensing information.
        !            11:  */
        !            12:
        !            13: #include <curses.h>
        !            14: #include <sys/types.h>
        !            15: #include <sys/stat.h>
        !            16: #include <errno.h>
        !            17: #include <string.h>
        !            18: #include <stdlib.h>
        !            19: #include <time.h>
        !            20: #define KERNEL
        !            21: #include <signal.h>
        !            22: #undef KERNEL
        !            23: #include "rogue.h"
        !            24:
        !            25: void save_file(FILE *savef);
        !            26: extern int rs_save_file(FILE *savef);
        !            27: extern int rs_restore_file(FILE *inf);
        !            28:
        !            29: typedef struct stat STAT;
        !            30:
        !            31: extern char version[], encstr[];
        !            32: extern bool _endwin;
        !            33:
        !            34: STAT sbuf;
        !            35:
        !            36: /*
        !            37:  * save_game:
        !            38:  *     Implement the "save game" command
        !            39:  */
        !            40: /* This has to be cleaned up, these goto's are annoying. */
        !            41: bool
        !            42: save_game(void)
        !            43: {
        !            44:     register FILE *savef;
        !            45:     register int c;
        !            46:     char buf[256];
        !            47:
        !            48:     /*
        !            49:      * get file name
        !            50:      */
        !            51:     mpos = 0;
        !            52: over:
        !            53:     if (file_name[0] != '\0')
        !            54:     {
        !            55:        for (;;)
        !            56:        {
        !            57:            if (use_savedir)
        !            58:                msg("Save game? ");
        !            59:            else
        !            60:                msg("save file (%s)? ", file_name);
        !            61:            c = getchar();
        !            62:            mpos = 0;
        !            63:            if (c == ESCAPE)
        !            64:            {
        !            65:                msg("");
        !            66:                return FALSE;
        !            67:            }
        !            68:            else if (c == 'n' || c == 'N' || c == 'y' || c == 'Y')
        !            69:                break;
        !            70:            else
        !            71:                msg("please answer Y or N");
        !            72:        }
        !            73:        if (c == 'y' || c == 'Y')
        !            74:        {
        !            75:            strcpy(buf, file_name);
        !            76:            goto gotfile;
        !            77:        }
        !            78:     }
        !            79:
        !            80:     if (use_savedir)
        !            81:     {
        !            82:         /* You can't change the savefile if you're using the system
        !            83:            savedir, because that means you have privileges. */
        !            84:         msg("");
        !            85:         return FALSE;
        !            86:     }
        !            87:
        !            88:     do
        !            89:     {
        !            90:        mpos = 0;
        !            91:        msg("file name: ");
        !            92:        buf[0] = '\0';
        !            93:        if (get_str(buf, stdscr) == QUIT)
        !            94:        {
        !            95: quit:
        !            96:            msg("");
        !            97:            return FALSE;
        !            98:        }
        !            99:        mpos = 0;
        !           100: gotfile:
        !           101:        /*
        !           102:         * test to see if the file exists
        !           103:         */
        !           104:        if (stat(buf, &sbuf) >= 0)
        !           105:        {
        !           106:            for (;;)
        !           107:            {
        !           108:                msg("File exists.  Do you wish to overwrite it?");
        !           109:                mpos = 0;
        !           110:                if ((c = readchar()) == ESCAPE)
        !           111:                    goto quit;
        !           112:                if (c == 'y' || c == 'Y')
        !           113:                    break;
        !           114:                else if (c == 'n' || c == 'N')
        !           115:                    goto over;
        !           116:                else
        !           117:                    msg("Please answer Y or N");
        !           118:            }
        !           119:            msg("file name: %s", buf);
        !           120:        }
        !           121:        strcpy(file_name, buf);
        !           122:        if ((savef = fopen(file_name, "w")) == NULL)
        !           123:         {
        !           124:            msg(strerror(errno));       /* fake perror() */
        !           125:             if (use_savedir)
        !           126:                 return FALSE;
        !           127:         }
        !           128:     } while (savef == NULL);
        !           129:
        !           130:     /*
        !           131:      * write out encrpyted file (after a stat)
        !           132:      * The fwrite is to force allocation of the buffer before the write
        !           133:      */
        !           134:     save_file(savef);
        !           135:     return TRUE;
        !           136: }
        !           137:
        !           138: /*
        !           139:  * auto_save:
        !           140:  *     Automatically save a file.  This is used if a HUP signal is
        !           141:  *     recieved
        !           142:  */
        !           143: void
        !           144: auto_save(int sig)
        !           145: {
        !           146:     register FILE *savef;
        !           147:
        !           148:     md_ignore_signals();
        !           149:
        !           150:     if (file_name[0] != '\0' && (savef = fopen(file_name, "w")) != NULL)
        !           151:        save_file(savef);
        !           152:     endwin();
        !           153:     exit(1);
        !           154: }
        !           155:
        !           156: /*
        !           157:  * save_file:
        !           158:  *     Write the saved game on the file
        !           159:  */
        !           160: void
        !           161: save_file(FILE *savef)
        !           162: {
        !           163:     int slines = LINES;
        !           164:     int scols  = COLS;
        !           165:
        !           166:     /*
        !           167:      * close any open score file
        !           168:      */
        !           169:     if (score_file != NULL) {
        !           170:         fclose(score_file);
        !           171:         score_file = NULL;
        !           172:     }
        !           173:     move(LINES-1, 0);
        !           174:     refresh();
        !           175:     fstat(md_fileno(savef), &sbuf);
        !           176:     /*
        !           177:      * DO NOT DELETE.  This forces stdio to allocate the output buffer
        !           178:      * so that malloc doesn't get confused on restart
        !           179:      */
        !           180:     fwrite("junk", 1, 5, savef);
        !           181:
        !           182:     fseek(savef, 0L, 0);
        !           183:
        !           184:     encwrite(version,strlen(version)+1,savef);
        !           185:     encwrite(&slines,sizeof(slines),savef);
        !           186:     encwrite(&scols,sizeof(scols),savef);
        !           187:        msg("");
        !           188:     rs_save_file(savef);
        !           189:
        !           190:     fclose(savef);
        !           191: }
        !           192:
        !           193: /*
        !           194:  * restore:
        !           195:  *     Restore a saved game from a file with elaborate checks for file
        !           196:  *     integrity from cheaters
        !           197:  */
        !           198: bool
        !           199: restore(char *file, char **envp)
        !           200: {
        !           201:     FILE *inf;
        !           202:     register bool syml;
        !           203:     extern char **environ;
        !           204:     char buf[MAXSTR];
        !           205:     STAT sbuf2;
        !           206:     int slines, scols;
        !           207:
        !           208:     if (strcmp(file, "-r") == 0)
        !           209:        file = file_name;
        !           210:
        !           211: #ifdef SIGTSTP
        !           212:     /*
        !           213:      * If a process can be suspended, this code wouldn't work
        !           214:      */
        !           215:     signal(SIGTSTP, SIG_IGN);
        !           216: #endif
        !           217:
        !           218:     if ((inf = fopen(file, "r")) == NULL)
        !           219:     {
        !           220:         if (use_savedir && errno == ENOENT)
        !           221:         {
        !           222:             /* We're using a system savefile which doesn't exist.
        !           223:                This isn't a fatal error, it means start a new game. */
        !           224:             return TRUE;
        !           225:         }
        !           226:        perror(file);
        !           227:        return FALSE;
        !           228:     }
        !           229:
        !           230:     fflush(stdout);
        !           231:     encread(buf, strlen(version) + 1, inf);
        !           232:     if (strcmp(buf, version) != 0)
        !           233:     {
        !           234:         printf("Sorry, saved game is out of date.\n");
        !           235:         return FALSE;
        !           236:     }
        !           237:
        !           238:     stat(file, &sbuf2);
        !           239:     fflush(stdout);
        !           240:     syml = issymlink(file);
        !           241:
        !           242:     fflush(stdout);
        !           243:
        !           244:     encread(&slines,sizeof(slines),inf);
        !           245:     encread(&scols,sizeof(scols),inf);
        !           246:
        !           247:     /*
        !           248:      * we do not close the file so that we will have a hold of the
        !           249:      * inode for as long as possible
        !           250:      */
        !           251:
        !           252:     initscr();
        !           253:
        !           254:     if (slines > LINES)
        !           255:     {
        !           256:         endwin();
        !           257:         printf("Sorry, original game was played on a screen with %d lines.\n",slines);
        !           258:         printf("Current screen only has %d lines. Unable to restore game\n",LINES);
        !           259:         return(FALSE);
        !           260:     }
        !           261:
        !           262:     if (scols > COLS)
        !           263:     {
        !           264:         endwin();
        !           265:         printf("Sorry, original game was played on a screen with %d columns.\n",scols);
        !           266:         printf("Current screen only has %d columns. Unable to restore game\n",COLS);
        !           267:         return(FALSE);
        !           268:     }
        !           269:
        !           270:     hw = newwin(LINES, COLS, 0, 0);
        !           271:     keypad(stdscr,1);
        !           272:
        !           273:     mpos = 0;
        !           274:     mvprintw(0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime));
        !           275:
        !           276:     if (rs_restore_file(inf) == FALSE)
        !           277:     {
        !           278:        endwin();
        !           279:         printf("Cannot restore file\n");
        !           280:         return(FALSE);
        !           281:     }
        !           282:
        !           283:     if (
        !           284: #ifdef WIZARD
        !           285:        !wizard &&
        !           286: #endif
        !           287:     md_unlink_open_file(file, inf) < 0)
        !           288:     {
        !           289:         endwin();
        !           290:        printf("Cannot unlink file\n");
        !           291:        return FALSE;
        !           292:     }
        !           293:
        !           294:     /*
        !           295:      * defeat multiple restarting from the same place
        !           296:      */
        !           297: #ifdef WIZARD
        !           298:     if (!wizard)
        !           299: #endif
        !           300:        if (sbuf2.st_nlink != 1 || syml)
        !           301:        {
        !           302:             endwin();
        !           303:            printf("Cannot restore from a linked file\n");
        !           304:            return FALSE;
        !           305:        }
        !           306:
        !           307:     if (pstats.s_hpt <= 0) {
        !           308:         endwin();
        !           309:         printf("This character is already dead.\n");
        !           310:         return FALSE;
        !           311:     }
        !           312:
        !           313: #ifdef SIGTSTP
        !           314:     signal(SIGTSTP, tstp);
        !           315: #endif
        !           316:     environ = envp;
        !           317:     strcpy(file_name, file);
        !           318:     setup();
        !           319:     clearok(curscr, TRUE);
        !           320:     touchwin(stdscr);
        !           321:     srand(md_random_seed());
        !           322:     msg("file name: %s", file);
        !           323:        status();
        !           324:     playit();
        !           325:     return 0;
        !           326: }
        !           327:
        !           328: /*
        !           329:  * encwrite:
        !           330:  *     Perform an encrypted write
        !           331:  */
        !           332: void
        !           333: encwrite(void *starta, int size, FILE *outf)
        !           334: {
        !           335:     register char *ep;
        !           336:     register char *start = (char *) starta;
        !           337:     ep = encstr;
        !           338:
        !           339:     while (size--)
        !           340:     {
        !           341:        putc(*start++ ^ *ep++, outf);
        !           342:        if (*ep == '\0')
        !           343:            ep = encstr;
        !           344:     }
        !           345: }
        !           346:
        !           347: /*
        !           348:  * encread:
        !           349:  *     Perform an encrypted read
        !           350:  */
        !           351: int
        !           352: encread(void *starta, int size, FILE *inf)
        !           353: {
        !           354:     register char *ep;
        !           355:     register int read_size;
        !           356:     register char *start = (char *) starta;
        !           357:
        !           358:     if ((read_size = fread(start, 1, size, inf)) == 0)
        !           359:        return read_size;
        !           360:
        !           361:     ep = encstr;
        !           362:
        !           363:     while (size--)
        !           364:     {
        !           365:        *start++ ^= *ep++;
        !           366:        if (*ep == '\0')
        !           367:            ep = encstr;
        !           368:     }
        !           369:
        !           370:     return read_size;
        !           371: }

CVSweb