Source:NetHack 3.0.0/unixunix.c

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

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   21. #include  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	   is that this include file 124.  * does not exist on all systems, and moreover, that it sometimes includes 125.  *  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  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. }