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