xref: /openbsd/games/mille/save.c (revision e5dd7070)
1 /*	$OpenBSD: save.c,v 1.14 2019/06/28 13:32:52 deraadt Exp $	*/
2 /*	$NetBSD: save.c,v 1.4 1995/03/24 05:02:13 cgd Exp $	*/
3 
4 /*
5  * Copyright (c) 1983, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #include <sys/stat.h>
34 
35 #include <err.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <string.h>
39 #include <time.h>
40 #include <unistd.h>
41 
42 #include "mille.h"
43 
44 /*
45  * @(#)save.c	1.2 (Berkeley) 3/28/83
46  */
47 
48 typedef	struct stat	STAT;
49 
50 /*
51  *	This routine saves the current game for use at a later date.
52  *	Returns FALSE if it couldn't be done.
53  */
54 bool
55 save(void)
56 {
57 	char	*sp;
58 	int	outf;
59 	time_t	*tp;
60 	char	buf[256];
61 	time_t	tme;
62 	STAT	junk;
63 	bool	rv;
64 
65 	sp = NULL;
66 	tp = &tme;
67 	if (Fromfile && getyn(SAMEFILEPROMPT))
68 		strlcpy(buf, Fromfile, sizeof(buf));
69 	else {
70 over:
71 		prompt(FILEPROMPT);
72 		leaveok(Board, FALSE);
73 		refresh();
74 		sp = buf;
75 		while ((*sp = readch()) != '\n' && *sp != '\r' &&
76 		    (sp - buf < (int)sizeof(buf))) {
77 			if (*sp == killchar())
78 				goto over;
79 			else if (*sp == erasechar()) {
80 				if (--sp < buf)
81 					sp = buf;
82 				else {
83 					addch('\b');
84 					/*
85 					 * if the previous char was a control
86 					 * char, cover up two characters.
87 					 */
88 					if (*sp < ' ')
89 						addch('\b');
90 					clrtoeol();
91 				}
92 			}
93 			else {
94 				addstr(unctrl(*sp));
95 				++sp;
96 			}
97 			refresh();
98 		}
99 		*sp = '\0';
100 		leaveok(Board, TRUE);
101 	}
102 
103 	/*
104 	 * check for existing files, and confirm overwrite if needed
105 	 */
106 
107 	if (sp == buf || (!Fromfile && stat(buf, &junk) > -1
108 	    && getyn(OVERWRITEFILEPROMPT) == FALSE))
109 		return FALSE;
110 
111 	if ((outf = open(buf, O_CREAT | O_TRUNC | O_WRONLY, 0644)) == -1) {
112 		error(strerror(errno));
113 		return FALSE;
114 	}
115 	mvwaddstr(Score, ERR_Y, ERR_X, buf);
116 	wrefresh(Score);
117 	time(tp);			/* get current time		*/
118 	rv = varpush(outf, writev);
119 	close(outf);
120 	if (!rv)
121 		unlink(buf);
122 	else {
123 		strlcpy(buf, ctime(tp), sizeof buf);
124 		for (sp = buf; *sp != '\n'; sp++)
125 			continue;
126 		*sp = '\0';
127 		wprintw(Score, " [%s]", buf);
128 	}
129 	wclrtoeol(Score);
130 	wrefresh(Score);
131 	return rv;
132 }
133 
134 /*
135  *	This does the actual restoring.  It returns TRUE if the
136  * backup was made on exiting, in which case certain things must
137  * be cleaned up before the game starts.
138  */
139 bool
140 rest_f(const char *file)
141 {
142 	char	*sp;
143 	int	inf;
144 	char	buf[80];
145 	STAT	sbuf;
146 
147 	if ((inf = open(file, O_RDONLY)) == -1)
148 		err(1, "%s", file);
149 	if (fstat(inf, &sbuf) == -1)		/* get file stats	*/
150 		err(1, "%s", file);
151 	varpush(inf, readv);
152 	close(inf);
153 	strlcpy(buf, ctime(&sbuf.st_mtime), sizeof buf);
154 	for (sp = buf; *sp != '\n'; sp++)
155 		continue;
156 	*sp = '\0';
157 	/*
158 	 * initialize some necessary values
159 	 */
160 	(void)snprintf(Initstr, sizeof Initstr, "%s [%s]\n", file, buf);
161 	Fromfile = file;
162 	return !On_exit;
163 }
164