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