123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- /* $NetBSD: hack.save.c,v 1.8 2003/04/02 18:36:40 jsm Exp $ */
- /*
- * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
- * Amsterdam
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of the Stichting Centrum voor Wiskunde en
- * Informatica, nor the names of its contributors may be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /*
- * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include <sys/cdefs.h>
- #ifndef lint
- __RCSID("$NetBSD: hack.save.c,v 1.8 2003/04/02 18:36:40 jsm Exp $");
- #endif /* not lint */
- #include <signal.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include "hack.h"
- #include "extern.h"
- int
- dosave()
- {
- if (dosave0(0)) {
- settty("Be seeing you ...\n");
- exit(0);
- }
- return (0);
- }
- #ifndef NOSAVEONHANGUP
- void
- hangup(n)
- int n __attribute__((__unused__));
- {
- (void) dosave0(1);
- exit(1);
- }
- #endif /* NOSAVEONHANGUP */
- /* returns 1 if save successful */
- int
- dosave0(hu)
- int hu;
- {
- int fd, ofd;
- int tmp; /* not ! */
- (void) signal(SIGHUP, SIG_IGN);
- (void) signal(SIGINT, SIG_IGN);
- if ((fd = creat(SAVEF, FMASK)) < 0) {
- if (!hu)
- pline("Cannot open save file. (Continue or Quit)");
- (void) unlink(SAVEF); /* ab@unido */
- return (0);
- }
- if (flags.moonphase == FULL_MOON) /* ut-sally!fletcher */
- u.uluck--; /* and unido!ab */
- savelev(fd, dlevel);
- saveobjchn(fd, invent);
- saveobjchn(fd, fcobj);
- savemonchn(fd, fallen_down);
- tmp = getuid();
- bwrite(fd, (char *) &tmp, sizeof tmp);
- bwrite(fd, (char *) &flags, sizeof(struct flag));
- bwrite(fd, (char *) &dlevel, sizeof dlevel);
- bwrite(fd, (char *) &maxdlevel, sizeof maxdlevel);
- bwrite(fd, (char *) &moves, sizeof moves);
- bwrite(fd, (char *) &u, sizeof(struct you));
- if (u.ustuck)
- bwrite(fd, (char *) &(u.ustuck->m_id), sizeof u.ustuck->m_id);
- bwrite(fd, (char *) pl_character, sizeof pl_character);
- bwrite(fd, (char *) genocided, sizeof genocided);
- bwrite(fd, (char *) fut_geno, sizeof fut_geno);
- savenames(fd);
- for (tmp = 1; tmp <= maxdlevel; tmp++) {
- if (tmp == dlevel || !level_exists[tmp])
- continue;
- glo(tmp);
- if ((ofd = open(lock, O_RDONLY)) < 0) {
- if (!hu)
- pline("Error while saving: cannot read %s.", lock);
- (void) close(fd);
- (void) unlink(SAVEF);
- if (!hu)
- done("tricked");
- return (0);
- }
- getlev(ofd, hackpid, tmp);
- (void) close(ofd);
- bwrite(fd, (char *) &tmp, sizeof tmp); /* level number */
- savelev(fd, tmp); /* actual level */
- (void) unlink(lock);
- }
- (void) close(fd);
- glo(dlevel);
- (void) unlink(lock); /* get rid of current level --jgm */
- glo(0);
- (void) unlink(lock);
- return (1);
- }
- int
- dorecover(fd)
- int fd;
- {
- int nfd;
- int tmp; /* not a ! */
- unsigned mid; /* idem */
- struct obj *otmp;
- restoring = TRUE;
- getlev(fd, 0, 0);
- invent = restobjchn(fd);
- for (otmp = invent; otmp; otmp = otmp->nobj)
- if (otmp->owornmask)
- setworn(otmp, otmp->owornmask);
- fcobj = restobjchn(fd);
- fallen_down = restmonchn(fd);
- mread(fd, (char *) &tmp, sizeof tmp);
- if (tmp != (int)getuid()) { /* strange ... */
- (void) close(fd);
- (void) unlink(SAVEF);
- puts("Saved game was not yours.");
- restoring = FALSE;
- return (0);
- }
- mread(fd, (char *) &flags, sizeof(struct flag));
- mread(fd, (char *) &dlevel, sizeof dlevel);
- mread(fd, (char *) &maxdlevel, sizeof maxdlevel);
- mread(fd, (char *) &moves, sizeof moves);
- mread(fd, (char *) &u, sizeof(struct you));
- if (u.ustuck)
- mread(fd, (char *) &mid, sizeof mid);
- mread(fd, (char *) pl_character, sizeof pl_character);
- mread(fd, (char *) genocided, sizeof genocided);
- mread(fd, (char *) fut_geno, sizeof fut_geno);
- restnames(fd);
- while (1) {
- if (read(fd, (char *) &tmp, sizeof tmp) != sizeof tmp)
- break;
- getlev(fd, 0, tmp);
- glo(tmp);
- if ((nfd = creat(lock, FMASK)) < 0)
- panic("Cannot open temp file %s!\n", lock);
- savelev(nfd, tmp);
- (void) close(nfd);
- }
- (void) lseek(fd, (off_t) 0, SEEK_SET);
- getlev(fd, 0, 0);
- (void) close(fd);
- (void) unlink(SAVEF);
- if (Punished) {
- for (otmp = fobj; otmp; otmp = otmp->nobj)
- if (otmp->olet == CHAIN_SYM)
- goto chainfnd;
- panic("Cannot find the iron chain?");
- chainfnd:
- uchain = otmp;
- if (!uball) {
- for (otmp = fobj; otmp; otmp = otmp->nobj)
- if (otmp->olet == BALL_SYM && otmp->spe)
- goto ballfnd;
- panic("Cannot find the iron ball?");
- ballfnd:
- uball = otmp;
- }
- }
- if (u.ustuck) {
- struct monst *mtmp;
- for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
- if (mtmp->m_id == mid)
- goto monfnd;
- panic("Cannot find the monster ustuck.");
- monfnd:
- u.ustuck = mtmp;
- }
- #ifndef QUEST
- setsee(); /* only to recompute seelx etc. - these
- * weren't saved */
- #endif /* QUEST */
- docrt();
- restoring = FALSE;
- return (1);
- }
- struct obj *
- restobjchn(fd)
- int fd;
- {
- struct obj *otmp, *otmp2 = NULL;
- struct obj *first = 0;
- int xl;
- while (1) {
- mread(fd, (char *) &xl, sizeof(xl));
- if (xl == -1)
- break;
- otmp = newobj(xl);
- if (!first)
- first = otmp;
- else
- otmp2->nobj = otmp;
- mread(fd, (char *) otmp, (unsigned) xl + sizeof(struct obj));
- if (!otmp->o_id)
- otmp->o_id = flags.ident++;
- otmp2 = otmp;
- }
- if (first && otmp2->nobj) {
- impossible("Restobjchn: error reading objchn.");
- otmp2->nobj = 0;
- }
- return (first);
- }
- struct monst *
- restmonchn(fd)
- int fd;
- {
- struct monst *mtmp, *mtmp2 = NULL;
- struct monst *first = 0;
- int xl;
- struct permonst *monbegin;
- long differ;
- mread(fd, (char *) &monbegin, sizeof(monbegin));
- differ = (const char *) (&mons[0]) - (const char *) (monbegin);
- #ifdef lint
- /* suppress "used before set" warning from lint */
- mtmp2 = 0;
- #endif /* lint */
- while (1) {
- mread(fd, (char *) &xl, sizeof(xl));
- if (xl == -1)
- break;
- mtmp = newmonst(xl);
- if (!first)
- first = mtmp;
- else
- mtmp2->nmon = mtmp;
- mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst));
- if (!mtmp->m_id)
- mtmp->m_id = flags.ident++;
- mtmp->data = (const struct permonst *)
- ((const char *) mtmp->data + differ);
- if (mtmp->minvent)
- mtmp->minvent = restobjchn(fd);
- mtmp2 = mtmp;
- }
- if (first && mtmp2->nmon) {
- impossible("Restmonchn: error reading monchn.");
- mtmp2->nmon = 0;
- }
- return (first);
- }
|