1 /* SCCS Id: @(#)pcunix.c 3.4 1994/11/07 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
4
5 /* This file collects some Unix dependencies; pager.c contains some more */
6
7 #include "hack.h"
8 #include "wintty.h"
9
10 #include <sys/stat.h>
11 #if defined(WIN32) || defined(MSDOS)
12 #include <errno.h>
13 #endif
14
15 #if defined(WIN32) || defined(MSDOS)
16 extern char orgdir[];
17 # ifdef WIN32
18 extern void NDECL(backsp);
19 # endif
20 extern void NDECL(clear_screen);
21 #endif
22
23 #ifdef OVLB
24
25 #if 0
26 static struct stat buf;
27 #endif
28
29 # ifdef WANT_GETHDATE
30 static struct stat hbuf;
31 # endif
32
33 #ifdef PC_LOCKING
34 static int NDECL(eraseoldlocks);
35 #endif
36
37 #if 0
38 int
39 uptodate(fd)
40 int fd;
41 {
42 # ifdef WANT_GETHDATE
43 if(fstat(fd, &buf)) {
44 pline("Cannot get status of saved level? ");
45 return(0);
46 }
47 if(buf.st_mtime < hbuf.st_mtime) {
48 pline("Saved level is out of date. ");
49 return(0);
50 }
51 # else
52 # if (defined(MICRO) || defined(WIN32)) && !defined(NO_FSTAT)
53 if(fstat(fd, &buf)) {
54 if(moves > 1) pline("Cannot get status of saved level? ");
55 else pline("Cannot get status of saved game.");
56 return(0);
57 }
58 if(comp_times(buf.st_mtime)) {
59 if(moves > 1) pline("Saved level is out of date.");
60 else pline("Saved game is out of date. ");
61 /* This problem occurs enough times we need to give the player
62 * some more information about what causes it, and how to fix.
63 */
64 # ifdef MSDOS
65 pline("Make sure that your system's date and time are correct.");
66 pline("They must be more current than NetHack.EXE's date/time stamp.");
67 # endif /* MSDOS */
68 return(0);
69 }
70 # endif /* MICRO */
71 # endif /* WANT_GETHDATE */
72 return(1);
73 }
74 #endif
75
76 #ifdef PC_LOCKING
77 static int
eraseoldlocks()78 eraseoldlocks()
79 {
80 register int i;
81
82 /* cannot use maxledgerno() here, because we need to find a lock name
83 * before starting everything (including the dungeon initialization
84 * that sets astral_level, needed for maxledgerno()) up
85 */
86 for(i = 1; i <= MAXDUNGEON*MAXLEVEL + 1; i++) {
87 /* try to remove all */
88 set_levelfile_name(lock, i);
89 (void) unlink(fqname(lock, LEVELPREFIX, 0));
90 }
91 set_levelfile_name(lock, 0);
92 #ifdef HOLD_LOCKFILE_OPEN
93 really_close();
94 #endif
95 if(unlink(fqname(lock, LEVELPREFIX, 0)))
96 return 0; /* cannot remove it */
97 return(1); /* success! */
98 }
99
100 void
getlock()101 getlock()
102 {
103 register int fd, c, ci, ct, ern;
104 char tbuf[BUFSZ];
105 const char *fq_lock;
106 # if defined(MSDOS) && defined(NO_TERMS)
107 int grmode = iflags.grmode;
108 # endif
109 /* we ignore QUIT and INT at this point */
110 if (!lock_file(HLOCK, LOCKPREFIX, 10)) {
111 wait_synch();
112 # if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
113 chdirx(orgdir, 0);
114 # endif
115 error("Quitting.");
116 }
117
118 /* regularize(lock); */ /* already done in pcmain */
119 Sprintf(tbuf,"%s",fqname(lock, LEVELPREFIX, 0));
120 set_levelfile_name(lock, 0);
121 fq_lock = fqname(lock, LEVELPREFIX, 1);
122 if((fd = open(fq_lock,0)) == -1) {
123 if(errno == ENOENT) goto gotlock; /* no such file */
124 # if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
125 chdirx(orgdir, 0);
126 # endif
127 # if defined(WIN32) || defined(HOLD_LOCKFILE_OPEN)
128 # if defined(HOLD_LOCKFILE_OPEN)
129 if(errno == EACCES) {
130 #define OOPS_BUFSZ 512
131 char oops[OOPS_BUFSZ];
132 Strcpy(oops,
133 "\nThere are files from a game in progress under your name.");
134 Strcat(oops, "\nThe files are locked or inaccessible.");
135 Strcat(oops, " Is the other game still running?\n");
136 if (strlen(fq_lock) < ((OOPS_BUFSZ -16) - strlen(oops)))
137 Sprintf(eos(oops), "Cannot open %s", fq_lock);
138 Strcat(oops, "\n");
139 unlock_file(HLOCK);
140 error(oops);
141 } else
142 # endif
143 error("Bad directory or name: %s\n%s\n",
144 fq_lock, strerror(errno));
145 # else
146 perror(fq_lock);
147 # endif
148 unlock_file(HLOCK);
149 error("Cannot open %s", fq_lock);
150 }
151
152 (void) close(fd);
153
154 if(iflags.window_inited) {
155 # ifdef SELF_RECOVER
156 c = yn("There are files from a game in progress under your name. Recover?");
157 # else
158 pline("There is already a game in progress under your name.");
159 pline("You may be able to use \"recover %s\" to get it back.\n",tbuf);
160 c = yn("Do you want to destroy the old game?");
161 # endif
162 } else {
163 # if defined(MSDOS) && defined(NO_TERMS)
164 grmode = iflags.grmode;
165 if (grmode) gr_finish();
166 # endif
167 c = 'n';
168 ct = 0;
169 # ifdef SELF_RECOVER
170 msmsg(
171 "There are files from a game in progress under your name. Recover? [yn]");
172 # else
173 msmsg("\nThere is already a game in progress under your name.\n");
174 msmsg("If this is unexpected, you may be able to use \n");
175 msmsg("\"recover %s\" to get it back.",tbuf);
176 msmsg("\nDo you want to destroy the old game? [yn] ");
177 # endif
178 while ((ci=nhgetch()) != '\n') {
179 if (ct > 0) {
180 msmsg("\b \b");
181 ct = 0;
182 c = 'n';
183 }
184 if (ci == 'y' || ci == 'n' || ci == 'Y' || ci == 'N') {
185 ct = 1;
186 c = ci;
187 msmsg("%c",c);
188 }
189 }
190 }
191 if(c == 'y' || c == 'Y')
192 # ifndef SELF_RECOVER
193 if(eraseoldlocks()) {
194 # if defined(WIN32CON)
195 clear_screen(); /* display gets fouled up otherwise */
196 # endif
197 goto gotlock;
198 } else {
199 unlock_file(HLOCK);
200 # if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
201 chdirx(orgdir, 0);
202 # endif
203 error("Couldn't destroy old game.");
204 }
205 # else /*SELF_RECOVER*/
206 if(recover_savefile()) {
207 # if defined(WIN32CON)
208 clear_screen(); /* display gets fouled up otherwise */
209 # endif
210 goto gotlock;
211 } else {
212 unlock_file(HLOCK);
213 # if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
214 chdirx(orgdir, 0);
215 # endif
216 error("Couldn't recover old game.");
217 }
218 # endif /*SELF_RECOVER*/
219 else {
220 unlock_file(HLOCK);
221 # if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
222 chdirx(orgdir, 0);
223 # endif
224 error("%s", "Cannot start a new game.");
225 }
226
227 gotlock:
228 fd = creat(fq_lock, FCMASK);
229 if (fd == -1) ern = errno;
230 unlock_file(HLOCK);
231 if(fd == -1) {
232 # if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
233 chdirx(orgdir, 0);
234 # endif
235 # if defined(WIN32)
236 error("cannot creat file (%s.)\n%s\n%s\"%s\" exists?\n",
237 fq_lock, strerror(ern), " Are you sure that the directory",
238 fqn_prefix[LEVELPREFIX]);
239 # else
240 error("cannot creat file (%s.)", fq_lock);
241 # endif
242 } else {
243 if(write(fd, (char *) &hackpid, sizeof(hackpid))
244 != sizeof(hackpid)){
245 # if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
246 chdirx(orgdir, 0);
247 # endif
248 error("cannot write lock (%s)", fq_lock);
249 }
250 if(close(fd) == -1) {
251 # if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
252 chdirx(orgdir, 0);
253 # endif
254 error("cannot close lock (%s)", fq_lock);
255 }
256 }
257 # if defined(MSDOS) && defined(NO_TERMS)
258 if (grmode) gr_init();
259 # endif
260 }
261 #endif /* PC_LOCKING */
262
263 # ifndef WIN32
264 void
regularize(s)265 regularize(s)
266 /*
267 * normalize file name - we don't like .'s, /'s, spaces, and
268 * lots of other things
269 */
270 register char *s;
271 {
272 register char *lp;
273
274 for (lp = s; *lp; lp++)
275 if (*lp <= ' ' || *lp == '"' || (*lp >= '*' && *lp <= ',') ||
276 *lp == '.' || *lp == '/' || (*lp >= ':' && *lp <= '?') ||
277 # ifdef OS2
278 *lp == '&' || *lp == '(' || *lp == ')' ||
279 # endif
280 *lp == '|' || *lp >= 127 || (*lp >= '[' && *lp <= ']'))
281 *lp = '_';
282 }
283 # endif /* WIN32 */
284 #endif /* OVLB */
285
286
287 #ifdef __EMX__
seteuid(int i)288 void seteuid(int i){;}
289 #endif
290