date and time created 89/05/17 13:28:35 by bostic
[unix-history] / usr / src / games / adventure / save.c
CommitLineData
0294e1a5
RH
1/* save (III) J. Gillogly
2 * save user core image for restarting
3 * usage: save(<command file (argv[0] from main)>,<output file>)
4 * bugs
5 * - impure code (i.e. changes in instructions) is not handled
6 * (but people that do that get what they deserve)
7 */
8
699b2c2e 9static char sccsid[] = " save.c 4.3 89/03/05 ";
0294e1a5 10
699b2c2e 11#include <sys/file.h>
0294e1a5
RH
12#include <a.out.h>
13int filesize; /* accessible to caller */
14
15char *sbrk();
16
17save(cmdfile,outfile) /* save core image */
18char *cmdfile,*outfile;
19{ register char *c;
20 register int i,fd;
21 int fdaout;
22 struct exec header;
23 int counter;
24 char buff[512],pwbuf[120];
699b2c2e 25 fdaout = open(cmdfile, O_RDONLY, 0); /* open command */
0294e1a5 26 if (fdaout<0) return(-1); /* can do nothing without text */
0294e1a5
RH
27 if ((fd=creat(outfile,0755))== -1)
28 { printf("Cannot create %s\n",outfile);
29 return(-1);
30 }
31 /* can get the text segment from the command that we were
32 * called with, and change all data from uninitialized to
33 * initialized. It will start at the top again, so the user
34 * is responsible for checking whether it was restarted
35 * could ignore sbrks and breaks for the first pass
36 */
37 read(fdaout,&header,sizeof header);/* get the header */
38 header.a_bss = 0; /* no data uninitialized */
39 header.a_syms = 0; /* throw away symbol table */
40 switch (header.a_magic) /* find data segment */
41 { case 0407: /* non sharable code */
42 c = (char *) header.a_text;/* data starts right after text */
43 header.a_data=sbrk(0)-c; /* current size (incl allocs) */
44 break;
45 case 0410: /* sharable code */
46 c = (char *)
47#ifdef pdp11
48 (header.a_text /* starts after text */
49 & 0160000) /* on an 8K boundary */
50 + 020000; /* i.e. the next one up */
51#endif
52#ifdef vax
53 (header.a_text /* starts after text */
54 & 037777776000) /* on an 1K boundary */
55 + 02000; /* i.e. the next one up */
56#endif
7bd96c10
KM
57#ifdef tahoe
58 (header.a_text /* starts after text */
59 & 037777776000) /* on an 1K boundary */
60 + 02000; /* i.e. the next one up */
61#endif
0294e1a5
RH
62#ifdef z8000
63 (header.a_text /* starts after text */
64 & 0174000) /* on an 2K boundary */
65 + 004000; /* i.e. the next one up */
66#endif
67 header.a_data=sbrk(0)-c; /* current size (incl allocs) */
68 break;
69 case 0411: /* sharable with split i/d */
70 c = 0; /* can't reach text */
71 header.a_data=(int)sbrk(0);/* current size (incl allocs) */
72 break;
73 case 0413:
74 c = (char *) header.a_text;/* starts after text */
75 lseek(fdaout, 1024L, 0); /* skip unused part of 1st block*/
76 }
77 if (header.a_data<0) /* data area very big */
78 return(-1); /* fail for now */
79
80 filesize=sizeof header+header.a_text+header.a_data;
81 write(fd,&header,sizeof header); /* make the new header */
82 if (header.a_magic==0413)
83 lseek(fd, 1024L, 0); /* Start on 1K boundary */
84 counter=header.a_text; /* size of text */
85 while (counter>512) /* copy 512-byte blocks */
86 { read(fdaout,buff,512); /* as long as possible */
87 write(fd,buff,512);
88 counter -= 512;
89 }
90 read(fdaout,buff,counter); /* then pick up the rest */
91 write(fd,buff,counter);
92 write(fd,c,header.a_data); /* write all data in 1 glob */
93 close(fd);
94}