1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2 /* hack.save.c - version 1.0.3 */ 3 /* $FreeBSD: src/games/hack/hack.save.c,v 1.4 1999/11/16 10:26:37 marcel Exp $ */ 4 5 #include "hack.h" 6 7 extern char SAVEF[], nul[]; 8 9 static bool dosave0(int); 10 11 int 12 dosave(void) 13 { 14 if (dosave0(0)) { 15 settty("Be seeing you ...\n"); 16 exit(0); 17 } 18 return (0); 19 } 20 21 #ifndef NOSAVEONHANGUP 22 void 23 hangup(int n __unused) 24 { 25 dosave0(1); 26 exit(1); 27 } 28 #endif /* NOSAVEONHANGUP */ 29 30 /* returns 1 if save successful */ 31 static bool 32 dosave0(int hu) 33 { 34 int fd, ofd; 35 int tmp; /* not ! */ 36 37 signal(SIGHUP, SIG_IGN); 38 signal(SIGINT, SIG_IGN); 39 if ((fd = creat(SAVEF, FMASK)) < 0) { 40 if (!hu) 41 pline("Cannot open save file. (Continue or Quit)"); 42 unlink(SAVEF); /* ab@unido */ 43 return (0); 44 } 45 if (flags.moonphase == FULL_MOON) /* ut-sally!fletcher */ 46 u.uluck--; /* and unido!ab */ 47 savelev(fd, dlevel); 48 saveobjchn(fd, invent); 49 saveobjchn(fd, fcobj); 50 savemonchn(fd, fallen_down); 51 tmp = getuid(); 52 bwrite(fd, (char *)&tmp, sizeof(tmp)); 53 bwrite(fd, (char *)&flags, sizeof(struct flag)); 54 bwrite(fd, (char *)&dlevel, sizeof(dlevel)); 55 bwrite(fd, (char *)&maxdlevel, sizeof(maxdlevel)); 56 bwrite(fd, (char *)&moves, sizeof(moves)); 57 bwrite(fd, (char *)&u, sizeof(struct you)); 58 if (u.ustuck) 59 bwrite(fd, (char *)&(u.ustuck->m_id), sizeof(u.ustuck->m_id)); 60 bwrite(fd, (char *)pl_character, sizeof(pl_character)); 61 bwrite(fd, (char *)genocided, sizeof(genocided)); 62 bwrite(fd, (char *)fut_geno, sizeof(fut_geno)); 63 savenames(fd); 64 for (tmp = 1; tmp <= maxdlevel; tmp++) { 65 if (tmp == dlevel || !level_exists[tmp]) 66 continue; 67 glo(tmp); 68 if ((ofd = open(lock, O_RDONLY)) < 0) { 69 if (!hu) 70 pline("Error while saving: cannot read %s.", lock); 71 close(fd); 72 unlink(SAVEF); 73 if (!hu) 74 done("tricked"); 75 return (0); 76 } 77 getlev(ofd, hackpid, tmp); 78 close(ofd); 79 bwrite(fd, (char *)&tmp, sizeof(tmp)); /* level number */ 80 savelev(fd, tmp); /* actual level */ 81 unlink(lock); 82 } 83 close(fd); 84 glo(dlevel); 85 unlink(lock); /* get rid of current level --jgm */ 86 glo(0); 87 unlink(lock); 88 return (1); 89 } 90 91 bool 92 dorecover(int fd) 93 { 94 int nfd; 95 int tmp; /* not a ! */ 96 unsigned mid; /* idem */ 97 struct obj *otmp; 98 99 restoring = TRUE; 100 getlev(fd, 0, 0); 101 invent = restobjchn(fd); 102 for (otmp = invent; otmp; otmp = otmp->nobj) 103 if (otmp->owornmask) 104 setworn(otmp, otmp->owornmask); 105 fcobj = restobjchn(fd); 106 fallen_down = restmonchn(fd); 107 mread(fd, (char *)&tmp, sizeof(tmp)); 108 if (tmp != (int)getuid()) { /* strange ... */ 109 close(fd); 110 unlink(SAVEF); 111 puts("Saved game was not yours."); 112 restoring = FALSE; 113 return (0); 114 } 115 mread(fd, (char *)&flags, sizeof(struct flag)); 116 mread(fd, (char *)&dlevel, sizeof(dlevel)); 117 mread(fd, (char *)&maxdlevel, sizeof(maxdlevel)); 118 mread(fd, (char *)&moves, sizeof(moves)); 119 mread(fd, (char *)&u, sizeof(struct you)); 120 if (u.ustuck) 121 mread(fd, (char *)&mid, sizeof(mid)); 122 mread(fd, (char *)pl_character, sizeof(pl_character)); 123 mread(fd, (char *)genocided, sizeof(genocided)); 124 mread(fd, (char *)fut_geno, sizeof(fut_geno)); 125 restnames(fd); 126 for (;;) { 127 if (read(fd, (char *)&tmp, sizeof(tmp)) != sizeof(tmp)) 128 break; 129 getlev(fd, 0, tmp); 130 glo(tmp); 131 if ((nfd = creat(lock, FMASK)) < 0) 132 panic("Cannot open temp file %s!\n", lock); 133 savelev(nfd, tmp); 134 close(nfd); 135 } 136 lseek(fd, (off_t)0, SEEK_SET); 137 getlev(fd, 0, 0); 138 close(fd); 139 unlink(SAVEF); 140 if (Punished) { 141 for (otmp = fobj; otmp; otmp = otmp->nobj) 142 if (otmp->olet == CHAIN_SYM) 143 goto chainfnd; 144 panic("Cannot find the iron chain?"); 145 chainfnd: 146 uchain = otmp; 147 if (!uball) { 148 for (otmp = fobj; otmp; otmp = otmp->nobj) 149 if (otmp->olet == BALL_SYM && otmp->spe) 150 goto ballfnd; 151 panic("Cannot find the iron ball?"); 152 ballfnd: 153 uball = otmp; 154 } 155 } 156 if (u.ustuck) { 157 struct monst *mtmp; 158 159 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) 160 if (mtmp->m_id == mid) 161 goto monfnd; 162 panic("Cannot find the monster ustuck."); 163 monfnd: 164 u.ustuck = mtmp; 165 } 166 #ifndef QUEST 167 setsee(); /* only to recompute seelx etc. - these weren't saved */ 168 #endif /* QUEST */ 169 docrt(); 170 restoring = FALSE; 171 return (1); 172 } 173 174 struct obj * 175 restobjchn(int fd) 176 { 177 struct obj *otmp, *otmp2; 178 struct obj *first = NULL; 179 int xl; 180 181 /* suppress "used before set" warning from lint */ 182 otmp2 = NULL; 183 for (;;) { 184 mread(fd, (char *)&xl, sizeof(xl)); 185 if (xl == -1) 186 break; 187 otmp = newobj(xl); 188 if (!first) 189 first = otmp; 190 else 191 otmp2->nobj = otmp; 192 mread(fd, (char *)otmp, (unsigned)xl + sizeof(struct obj)); 193 if (!otmp->o_id) otmp->o_id = flags.ident++; 194 otmp2 = otmp; 195 } 196 if (first && otmp2->nobj) { 197 impossible("Restobjchn: error reading objchn."); 198 otmp2->nobj = 0; 199 } 200 return (first); 201 } 202 203 struct monst * 204 restmonchn(int fd) 205 { 206 struct monst *mtmp, *mtmp2; 207 struct monst *first = NULL; 208 int xl; 209 struct permonst *monbegin; 210 long differ; 211 212 mread(fd, (char *)&monbegin, sizeof(monbegin)); 213 differ = (char *)(&mons[0]) - (char *)(monbegin); 214 215 /* suppress "used before set" warning from lint */ 216 mtmp2 = NULL; 217 for (;;) { 218 mread(fd, (char *)&xl, sizeof(xl)); 219 if (xl == -1) 220 break; 221 mtmp = newmonst(xl); 222 if (!first) 223 first = mtmp; 224 else 225 mtmp2->nmon = mtmp; 226 mread(fd, (char *)mtmp, (unsigned)xl + sizeof(struct monst)); 227 if (!mtmp->m_id) 228 mtmp->m_id = flags.ident++; 229 mtmp->data = (struct permonst *) 230 ((char *)mtmp->data + differ); 231 if (mtmp->minvent) 232 mtmp->minvent = restobjchn(fd); 233 mtmp2 = mtmp; 234 } 235 if (first && mtmp2->nmon) { 236 impossible("Restmonchn: error reading monchn."); 237 mtmp2->nmon = 0; 238 } 239 return (first); 240 } 241