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
save(void)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
rest_f(const char * file)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