Difference between revisions of "Source:NetHack 3.0.0/save.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (NetHack 3.0.0/save.c moved to Source:NetHack 3.0.0/save.c: Robot: moved page) |
(No difference)
|
Latest revision as of 05:26, 4 March 2008
Below is the full text to save.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/save.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)save.c 3.0 89/04/13 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* block some unused #defines to avoid overloading some cpp's */ 6. #define MONATTK_H 7. #include "hack.h" 8. #include "lev.h" 9. 10. #ifdef WORM 11. #include "wseg.h" 12. #endif 13. 14. #ifndef TOS 15. #include <signal.h> 16. #endif /* !TOS */ 17. #ifdef EXPLORE_MODE 18. #include <fcntl.h> 19. #endif /* EXPLORE_MODE */ 20. 21. boolean hu; /* set during hang-up */ 22. 23. #if defined(DGK) && !defined(TOS) 24. struct finfo fileinfo[MAXLEVEL+1]; 25. long bytes_counted; 26. int count_only; 27. #else 28. boolean level_exists[MAXLEVEL+1]; 29. #endif 30. 31. #if defined(DGK) && !defined(TOS) 32. static void savelev0(); 33. #endif /* DGK && !TOS */ 34. static void saveobjchn(); 35. static void savemonchn(); 36. static void savegoldchn(); 37. static void savetrapchn(); 38. static void savegenoinfo(); 39. #if defined(DGK) && !defined(TOS) 40. static boolean swapout_oldest(); 41. static void copyfile(); 42. #endif /* defined(DGK) && !defined(TOS) */ 43. static void spill_objs(); 44. 45. int 46. dosave(){ 47. pline("Really save? "); /* especially useful if COMPRESS defined */ 48. if(yn() == 'n') { 49. clrlin(); 50. (void) fflush(stdout); 51. if(multi > 0) nomul(0); 52. } else { 53. #ifdef EXPLORE_MODE 54. if(!discover) { 55. pline("Do you want to create a non-scoring, restartable save file? "); 56. if(yn() == 'y') discover = TRUE; 57. } 58. #endif 59. clear_screen(); 60. (void) fflush(stdout); 61. hu = FALSE; 62. if(dosave0()) { 63. settty("Be seeing you...\n"); 64. exit(0); 65. } else (void)doredraw(); 66. } 67. return 0; 68. } 69. 70. #ifndef NOSAVEONHANGUP 71. int 72. hangup(){ 73. hu = TRUE; 74. (void) dosave0(); 75. exit(1); 76. return 0; 77. } 78. #endif 79. 80. /* returns 1 if save successful */ 81. int 82. dosave0() { 83. register int fd, ofd; 84. int tmp; /* not register ! */ 85. xchar ltmp; 86. #if defined(DGK) && !defined(TOS) 87. long fds, needed; 88. int mode; 89. #endif 90. #ifdef COMPRESS 91. char cmd[80]; 92. #endif 93. #ifdef UNIX 94. (void) signal(SIGHUP, SIG_IGN); 95. #endif 96. #if !defined(__TURBOC__) && !defined(TOS) 97. (void) signal(SIGINT, SIG_IGN); 98. #endif 99. 100. #ifdef MSDOS 101. # ifdef DGK 102. if(!hu && !saveDiskPrompt(0)) return 0; 103. # endif 104. # ifdef EXPLORE_MODE 105. if(!hu) { 106. 107. fd = open(SAVEF, O_RDONLY); 108. if (fd > 0) { 109. (void) close(fd); 110. clrlin(); 111. pline("There seems to be an old save file. Overwrite it? "); 112. if (yn() == 'n') return 0; 113. } 114. } 115. # endif 116. # ifdef TOS 117. fd = creat(SAVEF, FCMASK); 118. # else 119. fd = open(SAVEF, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK); 120. # endif 121. #else /* MSDOS */ 122. # ifdef EXPLORE_MODE 123. if(!hu) { 124. fd = open(SAVEF, O_RDONLY); 125. if (fd > 0) { 126. (void) close(fd); 127. clrlin(); 128. pline("There seems to be an old save file. Overwrite it? "); 129. if (yn() == 'n') return 0; 130. } 131. } 132. # endif 133. fd = creat(SAVEF, FCMASK); 134. #endif /* MSDOS */ 135. if(fd < 0) { 136. if(!hu) pline("Cannot open save file."); 137. (void) unlink(SAVEF); /* ab@unido */ 138. return(0); 139. } 140. if(flags.moonphase == FULL_MOON) /* ut-sally!fletcher */ 141. change_luck(-1); /* and unido!ab */ 142. home(); 143. cl_end(); 144. #if defined(DGK) && !defined(TOS) 145. if(!hu) msmsg("Saving: "); 146. mode = COUNT; 147. again: 148. savelev(fd, dlevel, mode); 149. /* count_only will be set properly by savelev */ 150. #else 151. savelev(fd,dlevel); 152. #endif 153. saveobjchn(fd, invent); 154. savemonchn(fd, fallen_down); 155. savegenoinfo(fd); 156. tmp = getuid(); 157. bwrite(fd, (genericptr_t) &tmp, sizeof tmp); 158. bwrite(fd, (genericptr_t) &flags, sizeof(struct flag)); 159. bwrite(fd, (genericptr_t) &dlevel, sizeof dlevel); 160. bwrite(fd, (genericptr_t) &maxdlevel, sizeof maxdlevel); 161. bwrite(fd, (genericptr_t) &moves, sizeof moves); 162. bwrite(fd, (genericptr_t) &wiz_level, sizeof wiz_level); 163. bwrite(fd, (genericptr_t) &medusa_level, sizeof medusa_level); 164. #ifdef ORACLE 165. bwrite(fd, (genericptr_t) &oracle_level, sizeof oracle_level); 166. #endif 167. #ifdef REINCARNATION 168. bwrite(fd, (genericptr_t) &rogue_level, sizeof rogue_level); 169. #endif 170. #ifdef STRONGHOLD 171. bwrite(fd, (genericptr_t) &stronghold_level, sizeof stronghold_level); 172. bwrite(fd, (genericptr_t) &tower_level, sizeof tower_level); 173. bwrite(fd, (genericptr_t) tune, sizeof tune); 174. # ifdef MUSIC 175. bwrite(fd, (genericptr_t) &music_heard, sizeof music_heard); 176. # endif 177. #endif 178. bwrite(fd, (genericptr_t) &is_maze_lev, sizeof is_maze_lev); 179. bwrite(fd, (genericptr_t) &u, sizeof(struct you)); 180. #ifdef SPELLS 181. bwrite(fd, (genericptr_t) spl_book, sizeof(struct spell) * (MAXSPELL + 1)); 182. #endif 183. if(u.ustuck) 184. bwrite(fd, (genericptr_t) &(u.ustuck->m_id), sizeof u.ustuck->m_id); 185. bwrite(fd, (genericptr_t) pl_character, sizeof pl_character); 186. bwrite(fd, (genericptr_t) pl_fruit, sizeof pl_fruit); 187. bwrite(fd, (genericptr_t) ¤t_fruit, sizeof current_fruit); 188. savefruitchn(fd); 189. savenames(fd); 190. #if defined(DGK) && !defined(TOS) 191. if (mode == COUNT) { 192. # ifdef ZEROCOMP 193. bflush(fd); 194. # endif 195. /* make sure there is enough disk space */ 196. needed = bytes_counted; 197. for (ltmp = 1; ltmp <= maxdlevel; ltmp++) 198. if (ltmp != dlevel && fileinfo[ltmp].where) 199. needed += fileinfo[ltmp].size + (sizeof ltmp); 200. fds = freediskspace(SAVEF); 201. if(needed > fds) { 202. if(!hu) { 203. pline("There is insufficient space on SAVE disk."); 204. pline("Require %ld bytes but only have %ld.", needed, 205. fds); 206. } 207. flushout(); 208. (void) close(fd); 209. (void) unlink(SAVEF); 210. return 0; 211. } 212. mode = WRITE; 213. goto again; 214. } 215. #endif 216. for(ltmp = (xchar)1; ltmp <= maxdlevel; ltmp++) { 217. #if defined(DGK) && !defined(TOS) 218. if (ltmp == dlevel || !fileinfo[ltmp].where) continue; 219. if (fileinfo[ltmp].where != ACTIVE) 220. swapin_file(ltmp); 221. #else 222. if(ltmp == dlevel || !level_exists[ltmp]) continue; 223. #endif 224. glo(ltmp); 225. #ifdef DGK 226. if(!hu) msmsg("."); 227. #endif 228. if((ofd = open(lock, OMASK)) < 0) { 229. if(!hu) pline("Error while saving: cannot read %s.", lock); 230. (void) close(fd); 231. (void) unlink(SAVEF); 232. if(!hu) done("tricked"); 233. return(0); 234. } 235. #ifdef ZEROCOMP 236. minit(); 237. #endif 238. getlev(ofd, hackpid, ltmp, FALSE); 239. (void) close(ofd); 240. bwrite(fd, (genericptr_t) <mp, sizeof ltmp); /* level number */ 241. #if defined(DGK) && !defined(TOS) 242. savelev(fd, ltmp, WRITE); /* actual level */ 243. #else 244. savelev(fd, ltmp); /* actual level */ 245. #endif 246. (void) unlink(lock); 247. } 248. #ifdef ZEROCOMP 249. bflush(fd); 250. #endif 251. (void) close(fd); 252. glo(dlevel); 253. (void) unlink(lock); /* get rid of current level --jgm */ 254. glo(0); 255. (void) unlink(lock); 256. #ifdef COMPRESS 257. Strcpy(cmd, COMPRESS); 258. Strcat(cmd, " "); 259. # ifdef COMPRESS_OPTIONS 260. Strcat(cmd, COMPRESS_OPTIONS); 261. Strcat(cmd, " "); 262. # endif 263. Strcat(cmd, SAVEF); 264. (void) system(cmd); 265. #endif 266. return(1); 267. } 268. 269. #if defined(DGK) && !defined(TOS) 270. boolean 271. savelev(fd, lev, mode) 272. int fd; 273. xchar lev; 274. int mode; 275. { 276. if (mode & COUNT) { 277. # ifdef ZEROCOMP /* should be superfluous */ 278. if (!count_only) /* did we just write? */ 279. bflush(0); 280. /*dbg();*/ 281. # endif 282. count_only = TRUE; 283. bytes_counted = 0; 284. savelev0(fd, lev); 285. while (bytes_counted > freediskspace(levels)) 286. if (!swapout_oldest()) 287. return FALSE; 288. } 289. if (mode & WRITE) { 290. # ifdef ZEROCOMP 291. if (mode & COUNT) /* did we just count? */ 292. bflush(fd); 293. # endif 294. count_only = FALSE; 295. bytes_counted = 0; 296. savelev0(fd, lev); 297. } 298. fileinfo[lev].where = ACTIVE; 299. fileinfo[lev].time = moves; 300. fileinfo[lev].size = bytes_counted; 301. return TRUE; 302. } 303. 304. static 305. void 306. savelev0(fd,lev) 307. #else 308. void 309. savelev(fd,lev) 310. #endif 311. int fd; 312. xchar lev; 313. { 314. #ifdef WORM 315. register struct wseg *wtmp; 316. register int tmp; 317. #endif 318. #ifdef TOS 319. short tlev; 320. #endif 321. 322. if(fd < 0) panic("Save on bad file!"); /* impossible */ 323. #if !defined(DGK) || defined(TOS) 324. if(lev >= 0 && lev <= MAXLEVEL) 325. level_exists[lev] = TRUE; 326. #endif 327. bwrite(fd,(genericptr_t) &hackpid,sizeof(hackpid)); 328. #ifdef TOS 329. tlev=lev; 330. bwrite(fd,(genericptr_t) &tlev,sizeof(tlev)); 331. #else 332. bwrite(fd,(genericptr_t) &lev,sizeof(lev)); 333. #endif 334. bwrite(fd,(genericptr_t) levl,sizeof(levl)); 335. #ifdef REINCARNATION 336. if(dlevel == rogue_level && lev != rogue_level) 337. /* save the symbols actually used to represent the level, not 338. * those in use for the current level (the default symbols used 339. * for rogue), since we will need to know whether to update 340. * the display of the screen when the game is restored under 341. * a potentially different value of showsyms from the 342. * environment */ 343. /* if a game is saved off the rogue level, the usual showsyms 344. * will be written out for the rogue level too, but they will 345. * be ignored on restore so it doesn't matter */ 346. bwrite(fd, (genericptr_t) &savesyms, sizeof(struct symbols)); 347. else 348. #endif 349. bwrite(fd, (genericptr_t) &showsyms, sizeof(struct symbols)); 350. bwrite(fd,(genericptr_t) &moves,sizeof(long)); 351. bwrite(fd,(genericptr_t) &xupstair,sizeof(xupstair)); 352. bwrite(fd,(genericptr_t) &yupstair,sizeof(yupstair)); 353. bwrite(fd,(genericptr_t) &xdnstair,sizeof(xdnstair)); 354. bwrite(fd,(genericptr_t) &ydnstair,sizeof(ydnstair)); 355. #ifdef STRONGHOLD 356. bwrite(fd,(genericptr_t) &xupladder,sizeof(xupladder)); 357. bwrite(fd,(genericptr_t) &yupladder,sizeof(yupladder)); 358. bwrite(fd,(genericptr_t) &xdnladder,sizeof(xdnladder)); 359. bwrite(fd,(genericptr_t) &ydnladder,sizeof(ydnladder)); 360. #endif 361. bwrite(fd,(genericptr_t) &fountsound,sizeof(fountsound)); 362. bwrite(fd,(genericptr_t) &sinksound,sizeof(sinksound)); 363. savemonchn(fd, fmon); 364. savegoldchn(fd, fgold); 365. savetrapchn(fd, ftrap); 366. 367. saveobjchn(fd, fobj); 368. saveobjchn(fd, billobjs); 369. 370. save_engravings(fd); 371. bwrite(fd,(genericptr_t) rooms,sizeof(rooms)); 372. bwrite(fd,(genericptr_t) doors,sizeof(doors)); 373. #ifdef WORM 374. bwrite(fd,(genericptr_t) wsegs,sizeof(wsegs)); 375. for(tmp=1; tmp<32; tmp++){ 376. for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg){ 377. bwrite(fd,(genericptr_t) wtmp,sizeof(struct wseg)); 378. } 379. #if defined(DGK) && !defined(TOS) 380. if (!count_only) 381. #endif 382. wsegs[tmp] = 0; 383. } 384. bwrite(fd,(genericptr_t) wgrowtime,sizeof(wgrowtime)); 385. #endif /* WORM /**/ 386. #if defined(DGK) && !defined(TOS) 387. if (count_only) return; 388. #endif 389. billobjs = 0; 390. fgold = 0; 391. ftrap = 0; 392. fmon = 0; 393. fobj = 0; 394. } 395. 396. #ifdef ZEROCOMP 397. 398. #define RLESC '\0' /* Leading character for run of LRESC's */ 399. #define flushoutrun(ln) bputc(RLESC); bputc(ln); ln = -1; 400. 401. static unsigned char outbuf[BUFSZ]; 402. static unsigned short outbufp = 0; 403. static short outrunlength = -1; 404. static int bwritefd; 405. 406. /*dbg() 407. { 408. if(!hu) printf("outbufp %d outrunlength %d\n", outbufp,outrunlength); 409. }*/ 410. 411. static void bputc(c) 412. unsigned char c; 413. { 414. # ifdef DGK 415. bytes_counted++; 416. if (count_only) 417. return; 418. # endif 419. if (outbufp >= BUFSZ) { 420. (void) write(bwritefd, outbuf, (int) BUFSZ); 421. outbufp = 0; 422. } 423. outbuf[outbufp++] = c; 424. } 425. 426. void 427. bflush(fd) /* flush run and buffer */ 428. register int fd; 429. { 430. bwritefd = fd; 431. if (outrunlength >= 0) { /* flush run */ 432. flushoutrun(outrunlength); 433. } 434. if (outbufp) { 435. #ifdef DGK 436. if (!count_only) /* flush buffer */ 437. #endif 438. (void) write(fd, outbuf, outbufp); 439. outbufp = 0; 440. } 441. /*printf("bflush()"); getret();*/ 442. } 443. 444. void 445. bwrite(fd, loc, num) 446. register int fd; 447. register genericptr_t loc; 448. register unsigned num; 449. { 450. bwritefd = fd; 451. for (; num; num--, ((char *)loc)++) { 452. if (*((char *)loc) == RLESC) { /* One more char in run */ 453. if (++outrunlength == 0xFF) { 454. flushoutrun(outrunlength); 455. } 456. } else { /* end of run */ 457. if (outrunlength >= 0) { /* flush run */ 458. flushoutrun(outrunlength); 459. } 460. bputc(*((char *)loc)); 461. } 462. } 463. } 464. 465. #else /* ZEROCOMP */ 466. 467. void 468. bwrite(fd,loc,num) 469. register int fd; 470. register genericptr_t loc; 471. register unsigned num; 472. { 473. #if defined(DGK) && !defined(TOS) 474. bytes_counted += num; 475. if (!count_only) 476. #endif 477. /* lint wants the 3rd arg of write to be an int; lint -p an unsigned */ 478. #if defined(BSD) || defined(ULTRIX) 479. if(write(fd, loc, (int)num) != (int)num) { 480. #else /* e.g. SYSV, __TURBOC__ */ 481. if(write(fd, loc, num) != num) { 482. #endif 483. if(!hu) panic("cannot write %u bytes to file #%d", num, fd); 484. else exit(1); 485. } 486. } 487. #endif /* ZEROCOMP */ 488. 489. static void 490. saveobjchn(fd,otmp) 491. register int fd; 492. register struct obj *otmp; 493. { 494. register struct obj *otmp2; 495. unsigned int xl; 496. int minusone = -1; 497. 498. while(otmp) { 499. if(Is_container(otmp)) /* unlink contained objects */ 500. spill_objs(otmp); /* (this rearranges the list) */ 501. 502. otmp2 = otmp->nobj; 503. xl = otmp->onamelth; 504. bwrite(fd, (genericptr_t) &xl, sizeof(int)); 505. bwrite(fd, (genericptr_t) otmp, xl + sizeof(struct obj)); 506. #if defined(DGK) && !defined(TOS) 507. if (!count_only) 508. #endif 509. free((genericptr_t) otmp); 510. otmp = otmp2; 511. } 512. bwrite(fd, (genericptr_t) &minusone, sizeof(int)); 513. } 514. 515. static void 516. savemonchn(fd,mtmp) 517. register int fd; 518. register struct monst *mtmp; 519. { 520. register struct monst *mtmp2; 521. unsigned int xl; 522. int minusone = -1; 523. struct permonst *monbegin = &mons[0]; 524. 525. bwrite(fd, (genericptr_t) &monbegin, sizeof(monbegin)); 526. 527. while(mtmp) { 528. mtmp2 = mtmp->nmon; 529. xl = mtmp->mxlth + mtmp->mnamelth; 530. bwrite(fd, (genericptr_t) &xl, sizeof(int)); 531. bwrite(fd, (genericptr_t) mtmp, xl + sizeof(struct monst)); 532. if(mtmp->minvent) saveobjchn(fd,mtmp->minvent); 533. #if defined(DGK) && !defined(TOS) 534. if (!count_only) 535. #endif 536. free((genericptr_t) mtmp); 537. mtmp = mtmp2; 538. } 539. bwrite(fd, (genericptr_t) &minusone, sizeof(int)); 540. } 541. 542. static void 543. savegoldchn(fd,gold) 544. register int fd; 545. register struct gold *gold; 546. { 547. register struct gold *gold2; 548. while(gold) { 549. gold2 = gold->ngold; 550. bwrite(fd, (genericptr_t) gold, sizeof(struct gold)); 551. #if defined(DGK) && !defined(TOS) 552. if (!count_only) 553. #endif 554. free((genericptr_t) gold); 555. gold = gold2; 556. } 557. bwrite(fd, (genericptr_t)nul, sizeof(struct gold)); 558. } 559. 560. static void 561. savetrapchn(fd,trap) 562. register int fd; 563. register struct trap *trap; 564. { 565. register struct trap *trap2; 566. while(trap) { 567. trap2 = trap->ntrap; 568. bwrite(fd, (genericptr_t) trap, sizeof(struct trap)); 569. #if defined(DGK) && !defined(TOS) 570. if (!count_only) 571. #endif 572. free((genericptr_t) trap); 573. trap = trap2; 574. } 575. bwrite(fd, (genericptr_t)nul, sizeof(struct trap)); 576. } 577. 578. /* save all the fruit names and ID's; this is used only in saving whole games 579. * (not levels) and in saving bones levels. When saving a bones level, 580. * we only want to save the fruits which exist on the bones level; the bones 581. * level routine marks nonexistent fruits by making the fid negative. 582. */ 583. void 584. savefruitchn(fd) 585. register int fd; 586. { 587. register struct fruit *f2; 588. while(ffruit) { 589. f2 = ffruit->nextf; 590. if (ffruit->fid >= 0) 591. bwrite(fd, (genericptr_t) ffruit, sizeof(struct fruit)); 592. free((genericptr_t) ffruit); 593. ffruit = f2; 594. } 595. bwrite(fd, (genericptr_t)nul, sizeof(struct fruit)); 596. } 597. 598. static void 599. savegenoinfo(fd) 600. register int fd; 601. { 602. register int i; 603. 604. for (i = 0; i < NUMMONS; i++) 605. bwrite(fd, (genericptr_t) &(mons[i].geno), sizeof(unsigned)); 606. } 607. 608. #if defined(DGK) && !defined(TOS) 609. boolean 610. swapin_file(lev) 611. int lev; 612. { 613. char to[PATHLEN], from[PATHLEN]; 614. 615. Sprintf(from, "%s%s", permbones, alllevels); 616. Sprintf(to, "%s%s", levels, alllevels); 617. name_file(from, lev); 618. name_file(to, lev); 619. while (fileinfo[lev].size > freediskspace(to)) 620. if (!swapout_oldest()) 621. return FALSE; 622. #ifdef WIZARD 623. if (wizard) { 624. pline("Swapping in `%s'", from); 625. (void) fflush(stdout); 626. } 627. #endif 628. copyfile(from, to); 629. (void) unlink(from); 630. fileinfo[lev].where = ACTIVE; 631. return TRUE; 632. } 633. 634. static boolean 635. swapout_oldest() { 636. char to[PATHLEN], from[PATHLEN]; 637. int i, oldest; 638. long oldtime; 639. 640. if (!ramdisk) 641. return FALSE; 642. for (i = 1, oldtime = 0, oldest = 0; i <= maxdlevel; i++) 643. if (fileinfo[i].where == ACTIVE 644. && (!oldtime || fileinfo[i].time < oldtime)) { 645. oldest = i; 646. oldtime = fileinfo[i].time; 647. } 648. if (!oldest) 649. return FALSE; 650. Sprintf(from, "%s%s", levels, alllevels); 651. Sprintf(to, "%s%s", permbones, alllevels); 652. name_file(from, oldest); 653. name_file(to, oldest); 654. #ifdef WIZARD 655. if (wizard) { 656. pline("Swapping out `%s'.", from); 657. (void) fflush(stdout); 658. } 659. #endif 660. copyfile(from, to); 661. (void) unlink(from); 662. fileinfo[oldest].where = SWAPPED; 663. return TRUE; 664. } 665. 666. static 667. void 668. copyfile(from, to) 669. char *from, *to; 670. { 671. char buf[BUFSIZ]; 672. int nfrom, nto, fdfrom, fdto; 673. 674. if ((fdfrom = open(from, O_RDONLY | O_BINARY, FCMASK)) < 0) 675. panic("Can't copy from %s !?", from); 676. if ((fdto = open(to, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK)) < 0) 677. panic("Can't copy to %s", to); 678. do { 679. nfrom = read(fdfrom, buf, BUFSIZ); 680. nto = write(fdto, buf, nfrom); 681. if (nto != nfrom) 682. panic("Copyfile failed!"); 683. } while (nfrom == BUFSIZ); 684. (void) close(fdfrom); 685. (void) close(fdto); 686. } 687. #endif 688. 689. /* 690. * "spill" objects out of containers (unlinking from the fcobj list). 691. * 692. * The objects will be rearranged, and properly aged. When we restore, they 693. * can be put back into their containers. By the time all of the calls to 694. * saveobjchn() been made, the fcobj list should be empty. Thus it need not 695. * be saved, and doing so could cause some strange addressing problems. 696. * 697. * NOTE: The cobj field is set to -1. It will be used as a flag to indicate 698. * that this object was previously in a container. 699. */ 700. 701. static void 702. spill_objs(cobj) 703. register struct obj *cobj; 704. { 705. register struct obj *otmp, *otmp2, *probj; 706. 707. #ifdef LINT 708. probj = (struct obj *)0; /* suppress "used before set" error */ 709. #endif 710. for(otmp = fcobj; otmp; otmp = otmp2) { 711. 712. otmp2 = otmp->nobj; 713. if(otmp->cobj == cobj) { 714. 715. if(cobj->cursed && rn2(2)) otmp->cursed = 1; 716. /* 717. * Place all of the objects in a given container after that container 718. * in the list. On restore, they should be able to be picked up and 719. * put back in. 720. */ 721. if(otmp == fcobj) fcobj = otmp2; 722. else probj->nobj = otmp2; 723. 724. otmp->nobj = cobj->nobj; 725. cobj->nobj = otmp; 726. otmp->cobj = (struct obj *)-1; 727. } else probj = otmp; 728. } 729. 730. }