|
|
researchv10 Norman
/*
* save and restore routines
*
* @(#)save.c 3.6 (Berkeley) 4/19/81
*/
#include <curses.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "rogue.h"
typedef struct stat STAT;
extern char *sys_errlist[], version[], encstr[];
extern bool _endwin;
extern int errno;
char *sbrk();
STAT sbuf;
save_game()
{
register FILE *savef;
register int c;
char buf[80];
/*
* get file name
*/
mpos = 0;
if (file_name[0] != '\0')
{
msg("Save file (\"%s\")? ", file_name);
do
{
c = getchar();
} while (c != 'n' && c != 'N' && c != 'y' && c != 'Y');
mpos = 0;
if (c == 'y' || c == 'Y')
{
msg("File name: %s", file_name);
goto gotfile;
}
}
do
{
msg("File name: ");
mpos = 0;
buf[0] = '\0';
if (get_str(buf, cw) == QUIT)
{
msg("");
return FALSE;
}
strcpy(file_name, buf);
gotfile:
if ((savef = fopen(file_name, "w")) == NULL)
msg(sys_errlist[errno]); /* fake perror() */
} while (savef == NULL);
/*
* write out encrpyted file (after a stat)
* The fwrite is to force allocation of the buffer before the write
*/
save_file(savef);
return TRUE;
}
/*
* automatically save a file. This is used if a HUP signal is
* recieved
*/
auto_save()
{
register FILE *savef;
if (file_name[0] != '\0' && (savef = fopen(file_name, "w")) != NULL)
save_file(savef);
exit(1);
}
/*
* write the saved game on the file
*/
save_file(savef)
register FILE *savef;
{
wmove(cw, LINES-1, 0);
draw(cw);
fstat(fileno(savef), &sbuf);
fwrite("junk", 1, 5, savef);
fseek(savef, 0L, 0);
_endwin = TRUE;
restfile = savef;
encwrite(version, sbrk(0) - version, savef);
fclose(savef);
}
restore(file, envp)
register char *file;
char **envp;
{
register int inf;
extern char **environ;
char buf[80];
STAT sbuf2;
int chflag = cheating;
if (strcmp(file, "-r") == 0)
file = file_name;
if ((inf = open(file, 0)) < 0)
{
perror(file);
return FALSE;
}
fflush(stdout);
encread(buf, strlen(version) + 1, inf);
if (strcmp(buf, version) != 0)
{
printf("Sorry, saved game is out of date.\n");
return FALSE;
}
fstat(inf, &sbuf2);
fflush(stdout);
brk(version + sbuf2.st_size);
lseek(inf, 0L, 0);
encread(version, (int) sbuf2.st_size, inf);
if (restfile) {
restfile->_file = -1;
fclose(restfile);
}
/*
* we do not close the file so that we will have a hold of the
* inode for as long as possible
*/
if (!wizard)
if (sbuf2.st_ino != sbuf.st_ino || sbuf2.st_dev != sbuf.st_dev)
{
printf("Sorry, saved game is not in the same file.\n");
return FALSE;
}
else if (sbuf2.st_ctime - sbuf.st_ctime > 15)
{
printf("Sorry, file has been touched.\n");
return FALSE;
}
mpos = 0;
mvwprintw(cw, 0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime));
/*
* defeat multiple restarting from the same place
*/
if (!wizard) {
if (sbuf2.st_nlink != 1)
{
printf("Cannot restore from a linked file\n");
return FALSE;
}
if (!cheating) {
if (unlink(file) < 0)
{
printf("Cannot unlink file\n");
return FALSE;
}
sbuf2.st_ino = 0;
stat(file, &sbuf2); /* defeat patching unlink */
if (sbuf2.st_ino == sbuf.st_ino) {
printf("Cheater!\n");
return FALSE;
}
}
}
cheating |= chflag;
environ = envp;
if (!My_term && isatty(2))
{
register char *sp;
_tty_ch = 2;
gettmode();
if ((sp = getenv("TERM")) == NULL)
sp = Def_term;
setterm(sp);
}
else
setterm(Def_term);
strcpy(file_name, file);
setup();
clearok(curscr, TRUE);
touchwin(cw);
srand(getpid());
playit();
/*NOTREACHED*/
}
/*
* perform an encrypted write
*/
encwrite(start, size, outf)
register char *start;
unsigned int size;
register FILE *outf;
{
register char *ep;
ep = encstr;
while (size--)
{
putc(*start++ ^ *ep++, outf);
if (*ep == '\0')
ep = encstr;
}
}
/*
* perform an encrypted read
*/
encread(start, size, inf)
register char *start;
unsigned int size;
register int inf;
{
register char *ep;
register int read_size;
if ((read_size = read(inf, start, size)) == -1 || read_size == 0)
return read_size;
ep = encstr;
while (size--)
{
*start++ ^= *ep++;
if (*ep == '\0')
ep = encstr;
}
return read_size;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.