MXDOMAIN compile flag no longer used
[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
7bd96c10 9static char sccsid[] = " save.c 4.2 86/11/17 ";
0294e1a5
RH
10
11#include <a.out.h>
12int filesize; /* accessible to caller */
13
14char *sbrk();
15
16save(cmdfile,outfile) /* save core image */
17char *cmdfile,*outfile;
18{ register char *c;
19 register int i,fd;
20 int fdaout;
21 struct exec header;
22 int counter;
23 char buff[512],pwbuf[120];
24 fdaout=getcmd(cmdfile); /* open command wherever it is */
25 if (fdaout<0) return(-1); /* can do nothing without text */
26 if ((fd=open(outfile,0))>0) /* this restriction is so that */
27 { printf("Can't use an existing file\n"); /* we don't try */
28 close(fd); /* to write over the commnd file*/
29 return(-1);
30 }
31 if ((fd=creat(outfile,0755))== -1)
32 { printf("Cannot create %s\n",outfile);
33 return(-1);
34 }
35 /* can get the text segment from the command that we were
36 * called with, and change all data from uninitialized to
37 * initialized. It will start at the top again, so the user
38 * is responsible for checking whether it was restarted
39 * could ignore sbrks and breaks for the first pass
40 */
41 read(fdaout,&header,sizeof header);/* get the header */
42 header.a_bss = 0; /* no data uninitialized */
43 header.a_syms = 0; /* throw away symbol table */
44 switch (header.a_magic) /* find data segment */
45 { case 0407: /* non sharable code */
46 c = (char *) header.a_text;/* data starts right after text */
47 header.a_data=sbrk(0)-c; /* current size (incl allocs) */
48 break;
49 case 0410: /* sharable code */
50 c = (char *)
51#ifdef pdp11
52 (header.a_text /* starts after text */
53 & 0160000) /* on an 8K boundary */
54 + 020000; /* i.e. the next one up */
55#endif
56#ifdef vax
57 (header.a_text /* starts after text */
58 & 037777776000) /* on an 1K boundary */
59 + 02000; /* i.e. the next one up */
60#endif
7bd96c10
KM
61#ifdef tahoe
62 (header.a_text /* starts after text */
63 & 037777776000) /* on an 1K boundary */
64 + 02000; /* i.e. the next one up */
65#endif
0294e1a5
RH
66#ifdef z8000
67 (header.a_text /* starts after text */
68 & 0174000) /* on an 2K boundary */
69 + 004000; /* i.e. the next one up */
70#endif
71 header.a_data=sbrk(0)-c; /* current size (incl allocs) */
72 break;
73 case 0411: /* sharable with split i/d */
74 c = 0; /* can't reach text */
75 header.a_data=(int)sbrk(0);/* current size (incl allocs) */
76 break;
77 case 0413:
78 c = (char *) header.a_text;/* starts after text */
79 lseek(fdaout, 1024L, 0); /* skip unused part of 1st block*/
80 }
81 if (header.a_data<0) /* data area very big */
82 return(-1); /* fail for now */
83
84 filesize=sizeof header+header.a_text+header.a_data;
85 write(fd,&header,sizeof header); /* make the new header */
86 if (header.a_magic==0413)
87 lseek(fd, 1024L, 0); /* Start on 1K boundary */
88 counter=header.a_text; /* size of text */
89 while (counter>512) /* copy 512-byte blocks */
90 { read(fdaout,buff,512); /* as long as possible */
91 write(fd,buff,512);
92 counter -= 512;
93 }
94 read(fdaout,buff,counter); /* then pick up the rest */
95 write(fd,buff,counter);
96 write(fd,c,header.a_data); /* write all data in 1 glob */
97 close(fd);
98}
99
100#define NULL 0
101
102char *execat(), *getenv();
103
104getcmd(command) /* get command name (wherever it is) like shell */
105char *command;
106{
107 char *pathstr;
108 register char *cp;
109 char fname[128];
110 int fd;
111
112 if ((pathstr = getenv("PATH")) == NULL)
113 pathstr = ":/bin:/usr/bin";
114 cp = index(command, '/')? "": pathstr;
115
116 do {
117 cp = execat(cp, command, fname);
118 if ((fd=open(fname,0))>0)
119 return(fd);
120 } while (cp);
121
122 printf("Couldn't open %s\n",command);
123 return(-1);
124}
125
126static char *
127execat(s1, s2, si)
128register char *s1, *s2;
129char *si;
130{
131 register char *s;
132
133 s = si;
134 while (*s1 && *s1 != ':' && *s1 != '-')
135 *s++ = *s1++;
136 if (si != s)
137 *s++ = '/';
138 while (*s2)
139 *s++ = *s2++;
140 *s = '\0';
141 return(*s1? ++s1: 0);
142}