OSDN Git Service

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