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