OSDN Git Service

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