Source:NetHack 3.0.0/unixunix.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to unixunix.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/unixunix.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)unixunix.c	3.0	88/04/13
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.    /*
8.     * The time is used for:
9.     *	- seed for rand()
10.    *	- year on tombstone and yymmdd in record file
11.    *	- phase of the moon (various monsters react to NEW_MOON or FULL_MOON)
12.    *	- night and midnight (the undead are dangerous at midnight)
13.    *	- determination of what files are "very old"
14.    */
15.   
16.   /* block some unused #defines to avoid overloading some cpp's */
17.   #define MONATTK_H
18.   #include "hack.h"	/* mainly for index() which depends on BSD */
19.   
20.   #include <errno.h>
21.   #include <sys/stat.h>
22.   
23.   void
24.   setrandom()
25.   {
26.   #ifdef SYSV
27.   	(void) Srand((long) time ((time_t *) 0));
28.   #else
29.   #ifdef ULTRIX
30.   	Srand((int)time((time_t *)0));
31.   #else
32.   	(void) Srand((int) time ((long *) 0));
33.   #endif /* ULTRIX */
34.   #endif /* SYSV */
35.   
36.   }
37.   
38.   static struct tm *
39.   getlt()
40.   {
41.   	time_t date;
42.   
43.   #ifdef BSD
44.   	(void) time((long *)(&date));
45.   #else
46.   	(void) time(&date);
47.   #endif
48.   #if defined(ULTRIX) || defined(BSD)
49.   	return(localtime((long *)(&date)));
50.   #else
51.   	return(localtime(&date));
52.   #endif /* ULTRIX */
53.   }
54.   
55.   int
56.   getyear()
57.   {
58.   	return(1900 + getlt()->tm_year);
59.   }
60.   
61.   char *
62.   getdate()
63.   {
64.   #ifdef LINT	/* static char datestr[7]; */
65.   	char datestr[7];
66.   #else
67.   	static char datestr[7];
68.   #endif
69.   	register struct tm *lt = getlt();
70.   
71.   	Sprintf(datestr, "%2d%2d%2d",
72.   		lt->tm_year, lt->tm_mon + 1, lt->tm_mday);
73.   	if(datestr[2] == ' ') datestr[2] = '0';
74.   	if(datestr[4] == ' ') datestr[4] = '0';
75.   	return(datestr);
76.   }
77.   
78.   int
79.   phase_of_the_moon()			/* 0-7, with 0: new, 4: full */
80.   {					/* moon period: 29.5306 days */
81.   					/* year: 365.2422 days */
82.   	register struct tm *lt = getlt();
83.   	register int epact, diy, goldn;
84.   
85.   	diy = lt->tm_yday;
86.   	goldn = (lt->tm_year % 19) + 1;
87.   	epact = (11 * goldn + 18) % 30;
88.   	if ((epact == 25 && goldn > 11) || epact == 24)
89.   		epact++;
90.   
91.   	return( (((((diy + epact) * 6) + 11) % 177) / 22) & 7 );
92.   }
93.   
94.   int
95.   night()
96.   {
97.   	register int hour = getlt()->tm_hour;
98.   
99.   	return(hour < 6 || hour > 21);
100.  }
101.  
102.  int
103.  midnight()
104.  {
105.  	return(getlt()->tm_hour == 0);
106.  }
107.  
108.  static struct stat buf, hbuf;
109.  
110.  void
111.  gethdate(name) char *name; {
112.  /* old version - for people short of space */
113.  /*
114.  /* register char *np;
115.  /*	if(stat(name, &hbuf))
116.  /*		error("Cannot get status of %s.",
117.  /*			(np = rindex(name, '/')) ? np+1 : name);
118.  /*
119.  /* version using PATH from: seismo!gregc@ucsf-cgl.ARPA (Greg Couch) */
120.  
121.  
122.  /*
123.   * The problem with   #include	<sys/param.h>   is that this include file
124.   * does not exist on all systems, and moreover, that it sometimes includes
125.   * <sys/types.h> again, so that the compiler sees these typedefs twice.
126.   */
127.  #define		MAXPATHLEN	1024
128.  
129.  register char *np, *path;
130.  char filename[MAXPATHLEN+1];
131.  	if (index(name, '/') != NULL || (path = getenv("PATH")) == NULL)
132.  		path = "";
133.  
134.  	for (;;) {
135.  		if ((np = index(path, ':')) == NULL)
136.  			np = path + strlen(path);	/* point to end str */
137.  		if (np - path <= 1)			/* %% */
138.  			Strcpy(filename, name);
139.  		else {
140.  			(void) strncpy(filename, path, np - path);
141.  			filename[np - path] = '/';
142.  			Strcpy(filename + (np - path) + 1, name);
143.  		}
144.  		if (stat(filename, &hbuf) == 0)
145.  			return;
146.  		if (*np == '\0')
147.  			break;
148.  		path = np + 1;
149.  	}
150.  	error("Cannot get status of %s.",
151.  		(np = rindex(name, '/')) ? np+1 : name);
152.  }
153.  
154.  int
155.  uptodate(fd)
156.  int fd;
157.  {
158.  	if(fstat(fd, &buf)) {
159.  		pline("Cannot get status of saved level? ");
160.  		return(0);
161.  	}
162.  	if(buf.st_mtime < hbuf.st_mtime) {
163.  		pline("Saved level is out of date. ");
164.  		return(0);
165.  	}
166.  	return(1);
167.  }
168.  
169.  /* see whether we should throw away this xlock file */
170.  static int
171.  veryold(fd)
172.  int fd;
173.  {
174.  	register int i;
175.  	time_t date;
176.  
177.  	if(fstat(fd, &buf)) return(0);			/* cannot get status */
178.  	if(buf.st_size != sizeof(int)) return(0);	/* not an xlock file */
179.  #ifdef BSD
180.  	(void) time((long *)(&date));
181.  #else
182.  	(void) time(&date);
183.  #endif
184.  	if(date - buf.st_mtime < 3L*24L*60L*60L) {	/* recent */
185.  		extern int errno;
186.  		int lockedpid;	/* should be the same size as hackpid */
187.  
188.  		if(read(fd, (char *)&lockedpid, sizeof(lockedpid)) !=
189.  			sizeof(lockedpid))
190.  			/* strange ... */
191.  			return(0);
192.  
193.  		/* From: Rick Adams <seismo!rick>
194.  		/* This will work on 4.1cbsd, 4.2bsd and system 3? & 5.
195.  		/* It will do nothing on V7 or 4.1bsd. */
196.  #ifndef NETWORK
197.  		/* It will do a VERY BAD THING if the playground is shared
198.  		   by more than one machine! -pem */
199.    		if(!(kill(lockedpid, 0) == -1 && errno == ESRCH))
200.  #endif
201.  			return(0);
202.  	}
203.  	(void) close(fd);
204.  	for(i = 1; i <= MAXLEVEL+1; i++) {		/* try to remove all */
205.  		glo(i);
206.  		(void) unlink(lock);
207.  	}
208.  	glo(0);
209.  	if(unlink(lock)) return(0);			/* cannot remove it */
210.  	return(1);					/* success! */
211.  }
212.  
213.  void
214.  getlock()
215.  {
216.  	extern int errno;
217.  	register int i = 0, fd;
218.  
219.  #ifdef HARD
220.  	/* idea from rpick%ucqais@uccba.uc.edu
221.  	 * prevent automated rerolling of characters
222.  	 * test input (fd0) so that tee'ing output to get a screen dump still
223.  	 * works
224.  	 * also incidentally prevents development of any hack-o-matic programs
225.  	 */
226.  	if (!isatty(0))
227.  		error("You must play from a terminal.");
228.  #endif
229.  
230.  	(void) fflush(stdout);
231.  
232.  	/* we ignore QUIT and INT at this point */
233.  	if (link(HLOCK, LLOCK) == -1) {
234.  		register int errnosv = errno;
235.  
236.  		perror(HLOCK);
237.  		Printf("Cannot link %s to %s\n", LLOCK, HLOCK);
238.  		switch(errnosv) {
239.  		case ENOENT:
240.  		    Printf("Perhaps there is no (empty) file %s ?\n", HLOCK);
241.  		    break;
242.  		case EACCES:
243.  		    Printf("It seems you don't have write permission here.\n");
244.  		    break;
245.  		case EEXIST:
246.  		    Printf("(Try again or rm %s.)\n", LLOCK);
247.  		    break;
248.  		default:
249.  		    Printf("I don't know what is wrong.");
250.  		}
251.  		getret();
252.  		error("");
253.  		/*NOTREACHED*/
254.  	}
255.  
256.  	regularize(lock);
257.  	glo(0);
258.  	if(locknum > 25) locknum = 25;
259.  
260.  	do {
261.  		if(locknum) lock[0] = 'a' + i++;
262.  
263.  		if((fd = open(lock, 0)) == -1) {
264.  			if(errno == ENOENT) goto gotlock;    /* no such file */
265.  			perror(lock);
266.  			(void) unlink(LLOCK);
267.  			error("Cannot open %s", lock);
268.  		}
269.  
270.  		if(veryold(fd))	/* if true, this closes fd and unlinks lock */
271.  			goto gotlock;
272.  		(void) close(fd);
273.  	} while(i < locknum);
274.  
275.  	(void) unlink(LLOCK);
276.  	error(locknum ? "Too many hacks running now."
277.  		      : "There is a game in progress under your name.");
278.  gotlock:
279.  	fd = creat(lock, FCMASK);
280.  	if(unlink(LLOCK) == -1)
281.  		error("Cannot unlink %s.", LLOCK);
282.  	if(fd == -1) {
283.  		error("cannot creat lock file.");
284.  	} else {
285.  		if(write(fd, (char *) &hackpid, sizeof(hackpid))
286.  		    != sizeof(hackpid)){
287.  			error("cannot write lock");
288.  		}
289.  		if(close(fd) == -1) {
290.  			error("cannot close lock");
291.  		}
292.  	}
293.  }	
294.  
295.  void
296.  regularize(s)	/* normalize file name - we don't like .'s, /'s, spaces */
297.  register char *s;
298.  {
299.  	register char *lp;
300.  
301.  	while((lp=index(s, '.')) || (lp=index(s, '/')) || (lp=index(s,' ')))
302.  		*lp = '_';
303.  #ifdef SYSV
304.  	/* avoid problems with 14 character file name limit */
305.  # ifdef COMPRESS
306.  	if(strlen(s) > 10)
307.  		/* leave room for .e from error and .Z from compress */
308.  		s[10] = '\0';
309.  # else
310.  	if(strlen(s) > 12)
311.  		/* leave room for .e from error */
312.  		s[12] = '\0';
313.  # endif
314.  #endif
315.  }