|
|
1.1 root 1: /*
2: * save and restore routines
3: *
4: * @(#)save.c 3.6 (Berkeley) 4/19/81
5: */
6:
7: #include <curses.h>
8: #include <ctype.h>
9: #include <sys/types.h>
10: #include <sys/stat.h>
11: #include "rogue.h"
12:
13: typedef struct stat STAT;
14:
15: extern char *sys_errlist[], version[], encstr[];
16: extern bool _endwin;
17: extern int errno;
18:
19: char *sbrk();
20:
21: STAT sbuf;
22:
23: save_game()
24: {
25: register FILE *savef;
26: register int c;
27: char buf[80];
28:
29: /*
30: * get file name
31: */
32: mpos = 0;
33: if (file_name[0] != '\0')
34: {
35: msg("Save file (\"%s\")? ", file_name);
36: do
37: {
38: c = getchar();
39: } while (c != 'n' && c != 'N' && c != 'y' && c != 'Y');
40: mpos = 0;
41: if (c == 'y' || c == 'Y')
42: {
43: msg("File name: %s", file_name);
44: goto gotfile;
45: }
46: }
47:
48: do
49: {
50: msg("File name: ");
51: mpos = 0;
52: buf[0] = '\0';
53: if (get_str(buf, cw) == QUIT)
54: {
55: msg("");
56: return FALSE;
57: }
58: strcpy(file_name, buf);
59: gotfile:
60: if ((savef = fopen(file_name, "w")) == NULL)
61: msg(sys_errlist[errno]); /* fake perror() */
62: } while (savef == NULL);
63:
64: /*
65: * write out encrpyted file (after a stat)
66: * The fwrite is to force allocation of the buffer before the write
67: */
68: save_file(savef);
69: return TRUE;
70: }
71:
72: /*
73: * automatically save a file. This is used if a HUP signal is
74: * recieved
75: */
76: auto_save()
77: {
78: register FILE *savef;
79:
80: if (file_name[0] != '\0' && (savef = fopen(file_name, "w")) != NULL)
81: save_file(savef);
82: exit(1);
83: }
84:
85: /*
86: * write the saved game on the file
87: */
88: save_file(savef)
89: register FILE *savef;
90: {
91: wmove(cw, LINES-1, 0);
92: draw(cw);
93: fstat(fileno(savef), &sbuf);
94: fwrite("junk", 1, 5, savef);
95: fseek(savef, 0L, 0);
96: _endwin = TRUE;
97: restfile = savef;
98: encwrite(version, sbrk(0) - version, savef);
99: fclose(savef);
100: }
101:
102: restore(file, envp)
103: register char *file;
104: char **envp;
105: {
106: register int inf;
107: extern char **environ;
108: char buf[80];
109: STAT sbuf2;
110: int chflag = cheating;
111:
112: if (strcmp(file, "-r") == 0)
113: file = file_name;
114: if ((inf = open(file, 0)) < 0)
115: {
116: perror(file);
117: return FALSE;
118: }
119:
120: fflush(stdout);
121: encread(buf, strlen(version) + 1, inf);
122: if (strcmp(buf, version) != 0)
123: {
124: printf("Sorry, saved game is out of date.\n");
125: return FALSE;
126: }
127:
128: fstat(inf, &sbuf2);
129: fflush(stdout);
130: brk(version + sbuf2.st_size);
131: lseek(inf, 0L, 0);
132: encread(version, (int) sbuf2.st_size, inf);
133: if (restfile) {
134: restfile->_file = -1;
135: fclose(restfile);
136: }
137: /*
138: * we do not close the file so that we will have a hold of the
139: * inode for as long as possible
140: */
141:
142: if (!wizard)
143: if (sbuf2.st_ino != sbuf.st_ino || sbuf2.st_dev != sbuf.st_dev)
144: {
145: printf("Sorry, saved game is not in the same file.\n");
146: return FALSE;
147: }
148: else if (sbuf2.st_ctime - sbuf.st_ctime > 15)
149: {
150: printf("Sorry, file has been touched.\n");
151: return FALSE;
152: }
153: mpos = 0;
154: mvwprintw(cw, 0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime));
155:
156: /*
157: * defeat multiple restarting from the same place
158: */
159: if (!wizard) {
160: if (sbuf2.st_nlink != 1)
161: {
162: printf("Cannot restore from a linked file\n");
163: return FALSE;
164: }
165: if (!cheating) {
166: if (unlink(file) < 0)
167: {
168: printf("Cannot unlink file\n");
169: return FALSE;
170: }
171: sbuf2.st_ino = 0;
172: stat(file, &sbuf2); /* defeat patching unlink */
173: if (sbuf2.st_ino == sbuf.st_ino) {
174: printf("Cheater!\n");
175: return FALSE;
176: }
177:
178: }
179: }
180: cheating |= chflag;
181: environ = envp;
182: if (!My_term && isatty(2))
183: {
184: register char *sp;
185:
186: _tty_ch = 2;
187: gettmode();
188: if ((sp = getenv("TERM")) == NULL)
189: sp = Def_term;
190: setterm(sp);
191: }
192: else
193: setterm(Def_term);
194: strcpy(file_name, file);
195: setup();
196: clearok(curscr, TRUE);
197: touchwin(cw);
198: srand(getpid());
199: playit();
200: /*NOTREACHED*/
201: }
202:
203: /*
204: * perform an encrypted write
205: */
206: encwrite(start, size, outf)
207: register char *start;
208: unsigned int size;
209: register FILE *outf;
210: {
211: register char *ep;
212:
213: ep = encstr;
214:
215: while (size--)
216: {
217: putc(*start++ ^ *ep++, outf);
218: if (*ep == '\0')
219: ep = encstr;
220: }
221: }
222:
223: /*
224: * perform an encrypted read
225: */
226: encread(start, size, inf)
227: register char *start;
228: unsigned int size;
229: register int inf;
230: {
231: register char *ep;
232: register int read_size;
233:
234: if ((read_size = read(inf, start, size)) == -1 || read_size == 0)
235: return read_size;
236:
237: ep = encstr;
238:
239: while (size--)
240: {
241: *start++ ^= *ep++;
242: if (*ep == '\0')
243: ep = encstr;
244: }
245: return read_size;
246: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.