[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

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