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