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

Annotation of early-roguelike/rogue5/save.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:  * save and restore routines
                      3:  *
                      4:  * @(#)save.c  4.33 (Berkeley) 06/01/83
                      5:  *
                      6:  * Rogue: Exploring the Dungeons of Doom
                      7:  * Copyright (C) 1980-1983, 1985, 1999 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 <stdlib.h>
                     14: #include <sys/types.h>
                     15: #include <sys/stat.h>
                     16: #include <errno.h>
                     17: #include <signal.h>
                     18: #include <string.h>
                     19: #include <curses.h>
                     20: #include "rogue.h"
                     21: #include "score.h"
                     22:
                     23: /*
                     24:  * save_game:
                     25:  *     Implement the "save game" command
                     26:  */
                     27:
                     28: void
                     29: save_game(void)
                     30: {
                     31:     FILE *savef;
                     32:     int c;
                     33:     char buf[MAXSTR];
                     34:     struct stat sbuf;
                     35:     /*
                     36:      * get file name
                     37:      */
                     38:     mpos = 0;
                     39: over:
                     40:     if (file_name[0] != '\0')
                     41:     {
                     42:        for (;;)
                     43:        {
                     44:             if (use_savedir)
                     45:                 msg("Save game? ");
                     46:             else
                     47:                msg("Save file (%s)? ", file_name);
                     48:            c = readchar();
                     49:            mpos = 0;
                     50:            if (c == ESCAPE)
                     51:            {
                     52:                msg("");
                     53:                return;
                     54:            }
                     55:            else if (c == 'n' || c == 'N' || c == 'y' || c == 'Y')
                     56:                break;
                     57:            else
                     58:                msg("please answer Y or N");
                     59:        }
                     60:        if (c == 'y' || c == 'Y')
                     61:        {
                     62:            addstr("Yes\n");
                     63:            refresh();
                     64:            strcpy(buf, file_name);
                     65:            goto gotfile;
                     66:        }
                     67:     }
                     68:
                     69:     if (use_savedir) /* User chose N, changing location isn't allowed. */
                     70:         goto quit_it;
                     71:     do
                     72:     {
                     73:        mpos = 0;
                     74:        msg("file name: ");
                     75:        buf[0] = '\0';
                     76:        if (get_str(buf, stdscr) == QUIT)
                     77:        {
                     78: quit_it:
                     79:            msg("");
                     80:            return;
                     81:        }
                     82:        mpos = 0;
                     83: gotfile:
                     84:        /*
                     85:         * test to see if the file exists
                     86:         */
                     87:        if (stat(buf, &sbuf) >= 0 && !use_savedir)
                     88:        {
                     89:            for (;;)
                     90:            {
                     91:                msg("File exists.  Do you wish to overwrite it?");
                     92:                mpos = 0;
                     93:                if ((c = readchar()) == ESCAPE)
                     94:                    goto quit_it;
                     95:                if (c == 'y' || c == 'Y')
                     96:                    break;
                     97:                else if (c == 'n' || c == 'N')
                     98:                    goto over;
                     99:                else
                    100:                    msg("Please answer Y or N");
                    101:            }
                    102:            msg("file name: %s", buf);
                    103:            md_unlink(file_name);
                    104:        }
                    105:        strcpy(file_name, buf);
                    106:        if ((savef = fopen(file_name, "w")) == NULL)
                    107:         {
                    108:            msg(strerror(errno));
                    109:             if (use_savedir)
                    110:                 return;
                    111:         }
                    112:     } while (savef == NULL);
                    113:     msg("");
                    114:     save_file(savef);
                    115:     /* NOTREACHED */
                    116: }
                    117:
                    118: /*
                    119:  * auto_save:
                    120:  *     Automatically save a file.  This is used if a HUP signal is
                    121:  *     recieved
                    122:  */
                    123:
                    124: void
                    125: auto_save(int sig)
                    126: {
                    127:     FILE *savef;
                    128:     NOOP(sig);
                    129:
                    130:     md_ignoreallsignals();
                    131:     if (file_name[0] != '\0' && ((savef = fopen(file_name, "w")) != NULL ||
                    132:        (md_unlink_open_file(file_name, savef) >= 0 && (savef = fopen(file_name, "w")) != NULL)))
                    133:            save_file(savef);
                    134:     exit(0);
                    135: }
                    136:
                    137: /*
                    138:  * save_file:
                    139:  *     Write the saved game on the file
                    140:  */
                    141:
                    142: void
                    143: save_file(FILE *savef)
                    144: {
                    145:     char buf[80];
                    146:     mvcur(0, COLS - 1, LINES - 1, 0);
                    147:     putchar('\n');
                    148:     endwin();
                    149:     resetltchars();
                    150:     md_chmod(file_name, 0644);
                    151:     encwrite(version, strlen(version)+1, savef);
                    152:     sprintf(buf,"%d x %d\n", LINES, COLS);
                    153:     encwrite(buf,80,savef);
                    154:     rs_save_file(savef);
                    155:     fflush(savef);
                    156:     fclose(savef);
                    157:     printf("See you soon, %s!\n", whoami);
                    158:     exit(0);
                    159: }
                    160:
                    161: /*
                    162:  * restore:
                    163:  *     Restore a saved game from a file with elaborate checks for file
                    164:  *     integrity from cheaters
                    165:  */
                    166: int
                    167: restore(const char *file)
                    168: {
                    169:     FILE *inf;
                    170:     int syml;
                    171:     char buf[MAXSTR];
                    172:     struct stat sbuf2;
                    173:     int lines, cols;
                    174:
                    175:     if (strcmp(file, "-r") == 0)
                    176:        file = file_name;
                    177:
                    178:     md_tstphold();
                    179:
                    180:     if ((inf = fopen(file,"r")) == NULL)
                    181:     {
                    182:         /* If a system savefile doesn't exist, start a new game. */
                    183:         if (use_savedir && errno == ENOENT)
                    184:             return TRUE;
                    185:        perror(file);
                    186:        return FALSE;
                    187:     }
                    188:     stat(file, &sbuf2);
                    189:     syml = is_symlink(file);
                    190:
                    191:     fflush(stdout);
                    192:     encread(buf, strlen(version) + 1, inf);
                    193:     if (strcmp(buf, version) != 0)
                    194:     {
                    195:        printf("Sorry, saved game is out of date.\n");
                    196:        return FALSE;
                    197:     }
                    198:     encread(buf,80,inf);
                    199:     (void) sscanf(buf,"%d x %d\n", &lines, &cols);
                    200:
                    201:     initscr();                          /* Start up cursor package */
                    202:     keypad(stdscr, 1);
                    203:
                    204:     if (lines > LINES)
                    205:     {
                    206:         endwin();
                    207:         printf("Sorry, original game was played on a screen with %d lines.\n",lines);
                    208:         printf("Current screen only has %d lines. Unable to restore game\n",LINES);
                    209:         return(FALSE);
                    210:     }
                    211:     if (cols > COLS)
                    212:     {
                    213:         endwin();
                    214:         printf("Sorry, original game was played on a screen with %d columns.\n",cols);
                    215:         printf("Current screen only has %d columns. Unable to restore game\n",COLS);
                    216:         return(FALSE);
                    217:     }
                    218:
                    219:     hw = newwin(LINES, COLS, 0, 0);
                    220:     setup();
                    221:
                    222:     rs_restore_file(inf);
                    223:     /*
                    224:      * we do not close the file so that we will have a hold of the
                    225:      * inode for as long as possible
                    226:      */
                    227:
                    228:     if (
                    229: #ifdef MASTER
                    230:        !wizard &&
                    231: #endif
                    232:         md_unlink_open_file(file, inf) < 0)
                    233:     {
                    234:        printf("Cannot unlink file\n");
                    235:        return FALSE;
                    236:     }
                    237:     mpos = 0;
                    238: /*    printw(0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime)); */
                    239: /*
                    240:     printw("%s: %s", file, ctime(&sbuf2.st_mtime));
                    241: */
                    242:     clearok(stdscr,TRUE);
                    243:     /*
                    244:      * defeat multiple restarting from the same place
                    245:      */
                    246: #ifdef MASTER
                    247:     if (!wizard)
                    248: #endif
                    249:        if (sbuf2.st_nlink != 1 || syml)
                    250:        {
                    251:            endwin();
                    252:            printf("\nCannot restore from a linked file\n");
                    253:            return FALSE;
                    254:        }
                    255:
                    256:     if (pstats.s_hpt <= 0)
                    257:     {
                    258:        endwin();
                    259:        printf("\n\"He's dead, Jim\"\n");
                    260:        return FALSE;
                    261:     }
                    262:
                    263:        md_tstpresume();
                    264:
                    265:     strcpy(file_name, file);
                    266:     clearok(curscr, TRUE);
                    267:     srand(md_random_seed());
                    268:     msg("file name: %s", file);
                    269:     playit();
                    270:     /*NOTREACHED*/
                    271:     return(0);
                    272: }
                    273:
                    274: static int encerrno = 0;
                    275:
                    276: int
                    277: encerror()
                    278: {
                    279:     return encerrno;
                    280: }
                    281:
                    282: void
                    283: encseterr(int err)
                    284: {
                    285:     encerrno = err;
                    286: }
                    287:
                    288: int
                    289: encclearerr()
                    290: {
                    291:     int n = encerrno;
                    292:
                    293:     encerrno = 0;
                    294:
                    295:     return(n);
                    296: }
                    297:
                    298: /*
                    299:  * encwrite:
                    300:  *     Perform an encrypted write
                    301:  */
                    302:
                    303: size_t
                    304: encwrite(const char *start, size_t size, FILE *outf)
                    305: {
                    306:     const char *e1, *e2;
                    307:     char fb;
                    308:     int temp;
                    309:     size_t o_size = size;
                    310:     e1 = encstr;
                    311:     e2 = statlist;
                    312:     fb = 0;
                    313:
                    314:     if (encerrno) {
                    315:        errno = encerrno;
                    316:        return 0;
                    317:     }
                    318:
                    319:     while(size)
                    320:     {
                    321:        if (putc(*start++ ^ *e1 ^ *e2 ^ fb, outf) == EOF)
                    322:        {
                    323:            encerrno = errno;
                    324:             break;
                    325:        }
                    326:
                    327:        temp = *e1++;
                    328:        fb = fb + ((char) (temp * *e2++));
                    329:        if (*e1 == '\0')
                    330:            e1 = encstr;
                    331:        if (*e2 == '\0')
                    332:            e2 = statlist;
                    333:        size--;
                    334:     }
                    335:
                    336:     return(o_size - size);
                    337: }
                    338:
                    339: /*
                    340:  * encread:
                    341:  *     Perform an encrypted read
                    342:  */
                    343: size_t
                    344: encread(char *start, size_t size, FILE *inf)
                    345: {
                    346:     const char *e1, *e2;
                    347:     char fb;
                    348:     int temp;
                    349:     size_t read_size;
                    350:     size_t items;
                    351:     fb = 0;
                    352:
                    353:     if (encerrno) {
                    354:        errno = encerrno;
                    355:        return 0;
                    356:     }
                    357:
                    358:     items = read_size = fread(start,1,size,inf);
                    359:
                    360:     e1 = encstr;
                    361:     e2 = statlist;
                    362:
                    363:     while (read_size--)
                    364:     {
                    365:        *start++ ^= *e1 ^ *e2 ^ fb;
                    366:        temp = *e1++;
                    367:        fb = fb + (char)(temp * *e2++);
                    368:        if (*e1 == '\0')
                    369:            e1 = encstr;
                    370:        if (*e2 == '\0')
                    371:            e2 = statlist;
                    372:     }
                    373:
                    374:     if (items != size)
                    375:        encerrno = errno;
                    376:
                    377:     return(items);
                    378: }
                    379:
                    380: /*
                    381:  * read_scrore
                    382:  *     Read in the score file
                    383:  */
                    384: void
                    385: rd_score(SCORE *top_ten)
                    386: {
                    387:     char scoreline[100];
                    388:     int i;
                    389:
                    390:     if (scoreboard == NULL)
                    391:        return;
                    392:
                    393:     rewind(scoreboard);
                    394:
                    395:     for(i = 0; i < numscores; i++)
                    396:     {
                    397:         encread(top_ten[i].sc_name, MAXSTR, scoreboard);
                    398:        scoreline[0] = '\0';
                    399:         encread(scoreline, 100, scoreboard);
                    400:         (void) sscanf(scoreline, " %u %d %u %d %d %x \n",
                    401:             &top_ten[i].sc_uid, &top_ten[i].sc_score,
                    402:             &top_ten[i].sc_flags, &top_ten[i].sc_monster,
                    403:             &top_ten[i].sc_level, &top_ten[i].sc_time);
                    404:     }
                    405:
                    406:     rewind(scoreboard);
                    407: }
                    408:
                    409: /*
                    410:  * write_scrore
                    411:  *     Read in the score file
                    412:  */
                    413: void
                    414: wr_score(SCORE *top_ten)
                    415: {
                    416:     char scoreline[100];
                    417:     int i;
                    418:
                    419:     if (scoreboard == NULL)
                    420:        return;
                    421:
                    422:     rewind(scoreboard);
                    423:
                    424:     encerrno = 0;
                    425:     for(i = 0; i < numscores; i++)
                    426:     {
                    427:           memset(scoreline,0,100);
                    428:           encwrite(top_ten[i].sc_name, MAXSTR, scoreboard);
                    429:           sprintf(scoreline, " %u %d %u %u %d %x \n",
                    430:               top_ten[i].sc_uid, top_ten[i].sc_score,
                    431:               top_ten[i].sc_flags, top_ten[i].sc_monster,
                    432:               top_ten[i].sc_level, top_ten[i].sc_time);
                    433:           encwrite(scoreline,100,scoreboard);
                    434:     }
                    435:
                    436:     rewind(scoreboard);
                    437: }

CVSweb