xref: /original-bsd/games/adventure/save.c (revision 44811ff2)
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 
9 static char sccsid[] = "	save.c	4.3	89/03/05	";
10 
11 #include <sys/file.h>
12 #include <a.out.h>
13 int filesize;                    /* accessible to caller         */
14 
15 char *sbrk();
16 
17 save(cmdfile,outfile)                   /* save core image              */
18 char *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];
25 	fdaout = open(cmdfile, O_RDONLY, 0);	/* open command */
26 	if (fdaout<0) return(-1);       /* can do nothing without text  */
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
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
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 }
95