1 #include "config_local.h"
2
3 #include <stdio.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <signal.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10
11 #include "externs.h"
12 #include "globals.h"
13
14 static long savedbn;
15 static char *sfname;
16 static FILE *savefile;
17 static struct stat sfstat;
18
19 /* save out a game in a standard format. Uses the ntoh functions and hton
20 * functions so that the same save file will work on an MSB or LSB system
21 * other than that, it is a standard sokoban score file.
22 */
SaveGame(void)23 short SaveGame(void)
24 {
25 short ret = 0;
26
27 signal(SIGINT, SIG_IGN);
28 sfname = malloc(strlen(SAVEPATH) + strlen(username) + 6);
29 sprintf(sfname, "%s/%s.sav", SAVEPATH, username);
30
31 packets = htons(packets);
32 pushes = htons(pushes);
33 moves = htons(moves);
34 level = htons(level);
35 cols = htons(cols);
36 savepack = htons(savepack);
37 rows = htons(rows);
38 ppos.x = htons(ppos.x);
39 ppos.y = htons(ppos.y);
40
41 if ((savefile = fopen(sfname, "w")) == NULL)
42 ret = E_FOPENSAVE;
43 else {
44 savedbn = fileno(savefile);
45 if (write(savedbn, &(map[0][0]), MAXROW * MAXCOL) != MAXROW * MAXCOL)
46 ret = E_WRITESAVE;
47 else if (write(savedbn, &ppos, sizeof(POS)) != sizeof(POS))
48 ret = E_WRITESAVE;
49 else if (write(savedbn, &level, 2) != 2)
50 ret = E_WRITESAVE;
51 else if (write(savedbn, &moves, 2) != 2)
52 ret = E_WRITESAVE;
53 else if (write(savedbn, &pushes, 2) != 2)
54 ret = E_WRITESAVE;
55 else if (write(savedbn, &packets, 2) != 2)
56 ret = E_WRITESAVE;
57 else if (write(savedbn, &savepack, 2) != 2)
58 ret = E_WRITESAVE;
59 else if (write(savedbn, &rows, 2) != 2)
60 ret = E_WRITESAVE;
61 else if (write(savedbn, &cols, 2) != 2)
62 ret = E_WRITESAVE;
63 else
64 fclose(savefile);
65 if (stat(sfname, &sfstat) != 0)
66 ret = E_STATSAVE;
67 else if ((savefile = fopen(sfname, "a")) == NULL)
68 ret = E_FOPENSAVE;
69 else if (write(savedbn, &sfstat, sizeof(sfstat)) != sizeof(sfstat))
70 ret = E_WRITESAVE;
71 fclose(savefile);
72 }
73
74 ppos.x = ntohs(ppos.x);
75 ppos.y = ntohs(ppos.y);
76 pushes = ntohs(pushes);
77 moves = ntohs(moves);
78 level = ntohs(level);
79 packets = ntohs(packets);
80 cols = ntohs(cols);
81 rows = ntohs(rows);
82 savepack = ntohs(savepack);
83
84 if ((ret == E_WRITESAVE) || (ret == E_STATSAVE))
85 unlink(sfname);
86 signal(SIGINT, SIG_DFL);
87
88 free(sfname);
89 return ret;
90 }
91
92 /* loads in a previously saved game */
RestoreGame(void)93 short RestoreGame(void)
94 {
95 short ret = 0;
96 struct stat oldsfstat;
97
98 signal(SIGINT, SIG_IGN);
99 sfname = malloc(strlen(SAVEPATH) + strlen(username) + 6);
100 sprintf(sfname, "%s/%s.sav", SAVEPATH, username);
101
102 if (stat(sfname, &oldsfstat) < -1)
103 ret = E_NOSAVEFILE;
104 else {
105 if ((savefile = fopen(sfname, "r")) == NULL)
106 ret = E_FOPENSAVE;
107 else {
108 savedbn = fileno(savefile);
109 if (read(savedbn, &(map[0][0]), MAXROW * MAXCOL) != MAXROW * MAXCOL)
110 ret = E_READSAVE;
111 else if (read(savedbn, &ppos, sizeof(POS)) != sizeof(POS))
112 ret = E_READSAVE;
113 else if (read(savedbn, &level, 2) != 2)
114 ret = E_READSAVE;
115 else if (read(savedbn, &moves, 2) != 2)
116 ret = E_READSAVE;
117 else if (read(savedbn, &pushes, 2) != 2)
118 ret = E_READSAVE;
119 else if (read(savedbn, &packets, 2) != 2)
120 ret = E_READSAVE;
121 else if (read(savedbn, &savepack, 2) != 2)
122 ret = E_READSAVE;
123 else if (read(savedbn, &rows, 2) != 2)
124 ret = E_READSAVE;
125 else if (read(savedbn, &cols, 2) != 2)
126 ret = E_READSAVE;
127 else if (read(savedbn, &sfstat, sizeof(sfstat)) != sizeof(sfstat))
128 ret = E_READSAVE;
129 }
130
131 ppos.x = ntohs(ppos.x);
132 ppos.y = ntohs(ppos.y);
133 level = ntohs(level);
134 moves = ntohs(moves);
135 pushes = ntohs(pushes);
136 packets = ntohs(packets);
137 savepack = ntohs(savepack);
138 rows = ntohs(rows);
139 cols = ntohs(cols);
140
141 unlink(sfname);
142 }
143 signal(SIGINT, SIG_DFL);
144 free(sfname);
145 return ret;
146 }
147