Source:NetHack 3.0.0/unixunix.c
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. }