Difference between revisions of "Source:Hack 1.0/hack.main.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (Hack 1.0/hack.main.c moved to Source:Hack 1.0/hack.main.c: Robot: moved page) |
(No difference)
|
Latest revision as of 22:25, 3 March 2008
Below is the full text to hack.main.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.main.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
Screenshots and source code from Hack are used under the CWI license.
1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */ 2. 3. #include <stdio.h> 4. #include <signal.h> 5. #include <errno.h> 6. #include "hack.h" 7. 8. extern char *getlogin(); 9. extern char plname[PL_NSIZ], pl_character[PL_CSIZ]; 10. extern char *getenv(); 11. 12. int (*afternmv)(); 13. 14. int done1(); 15. int hangup(); 16. 17. char safelock[] = "safelock"; 18. xchar locknum; /* max num of players */ 19. char *catmore = "/bin/cat"; /* or e.g. /usr/ucb/more */ 20. char SAVEF[PL_NSIZ + 5] = "save/"; 21. char perm[] = "perm"; 22. char *hname; /* name of the game (argv[0] of call) */ 23. char obuf[BUFSIZ]; /* BUFSIZ is defined in stdio.h */ 24. 25. extern char *nomovemsg; 26. extern long wailmsg; 27. 28. main(argc,argv) 29. int argc; 30. char *argv[]; 31. { 32. int fd; 33. #ifdef NEWS 34. int nonews = 0; 35. #endif NEWS 36. char *dir; 37. 38. hname = argv[0]; 39. 40. /* 41. * See if we must change directory to the playground. 42. * (Perhaps hack runs suid and playground is inaccessible 43. * for the player.) 44. * The environment variable HACKDIR is overridden by a 45. * -d command line option. 46. */ 47. dir = getenv("HACKDIR"); 48. if(argc > 1 && !strncmp(argv[1], "-d", 2)) { 49. argc--; 50. argv++; 51. dir = argv[0]+2; 52. if(*dir == '=' || *dir == ':') dir++; 53. if(!*dir && argc > 1) { 54. argc--; 55. argv++; 56. dir = argv[0]; 57. } 58. if(!*dir) 59. error("Flag -d must be followed by a directory name."); 60. } 61. 62. /* 63. * Now we know the directory containing 'record' and 64. * may do a prscore(). 65. */ 66. if(argc > 1 && !strncmp(argv[1], "-s", 2)) { 67. if(dir) chdirx(dir); 68. prscore(argc, argv); 69. exit(0); 70. } 71. 72. /* 73. * It seems he really wants to play. Find the creation date of 74. * this game so as to avoid restoring outdated savefiles. 75. */ 76. gethdate(hname); 77. 78. /* 79. * We cannot do chdir earlier, otherwise gethdate will fail. 80. */ 81. if(dir) chdirx(dir); 82. 83. /* 84. * Who am i? Perhaps we should use $USER instead? 85. */ 86. (void) strncpy(plname, getlogin(), sizeof(plname)-1); 87. 88. /* 89. * Process options. 90. */ 91. while(argc > 1 && argv[1][0] == '-'){ 92. argv++; 93. argc--; 94. switch(argv[0][1]){ 95. #ifdef WIZARD 96. case 'w': 97. if(!strcmp(getlogin(), WIZARD)) 98. wizard = TRUE; 99. else printf("Sorry.\n"); 100. break; 101. #endif WIZARD 102. #ifdef NEWS 103. case 'n': 104. nonews++; 105. break; 106. #endif NEWS 107. case 'u': 108. if(argv[0][2]) 109. (void) strncpy(plname, argv[0]+2, sizeof(plname)-1); 110. else if(argc > 1) { 111. argc--; 112. argv++; 113. (void) strncpy(plname, argv[0], sizeof(plname)-1); 114. } else 115. printf("Player name expected after -u\n"); 116. break; 117. default: 118. printf("Unknown option: %s\n", *argv); 119. } 120. } 121. 122. if(argc > 1) 123. locknum = atoi(argv[1]); 124. if(argc > 2) 125. catmore = argv[2]; 126. #ifdef WIZARD 127. if(wizard) (void) strcpy(plname, "wizard"); else 128. #endif WIZARD 129. if(!*plname || !strncmp(plname, "player", 4)) askname(); 130. plnamesuffix(); /* strip suffix from name */ 131. 132. setbuf(stdout,obuf); 133. (void) srand(getpid()); 134. startup(); 135. cls(); 136. (void) signal(SIGHUP, hangup); 137. #ifdef WIZARD 138. if(!wizard) { 139. #endif WIZARD 140. (void) signal(SIGQUIT,SIG_IGN); 141. (void) signal(SIGINT,SIG_IGN); 142. if(locknum) 143. lockcheck(); 144. else 145. (void) strcpy(lock,plname); 146. #ifdef WIZARD 147. } else { 148. register char *sfoo; 149. (void) strcpy(lock,plname); 150. if(sfoo = getenv("MAGIC")) 151. while(*sfoo) { 152. switch(*sfoo++) { 153. case 'n': (void) srand(*sfoo++); 154. break; 155. } 156. } 157. if(sfoo = getenv("GENOCIDED")){ 158. if(*sfoo == '!'){ 159. extern struct permonst mons[CMNUM+2]; 160. extern char genocided[], fut_geno[]; 161. register struct permonst *pm = mons; 162. register char *gp = genocided; 163. 164. while(pm < mons+CMNUM+2){ 165. if(!index(sfoo, pm->mlet)) 166. *gp++ = pm->mlet; 167. pm++; 168. } 169. *gp = 0; 170. } else 171. (void) strcpy(genocided, sfoo); 172. (void) strcpy(fut_geno, genocided); 173. } 174. } 175. #endif WIZARD 176. u.uhp = 1; /* prevent RIP on early quits */ 177. u.ux = FAR; /* prevent nscr() */ 178. (void) strcat(SAVEF,plname); 179. if((fd = open(SAVEF,0)) >= 0 && 180. (uptodate(fd) || unlink(SAVEF) == 666)) { 181. (void) signal(SIGINT,done1); 182. puts("Restoring old save file..."); 183. (void) fflush(stdout); 184. dorecover(fd); 185. flags.move = 0; 186. } else { 187. #ifdef NEWS 188. if(!nonews) 189. if((fd = open(NEWS,0)) >= 0) 190. outnews(fd); 191. #endif NEWS 192. flags.ident = 1; 193. init_objects(); 194. u_init(); 195. (void) signal(SIGINT,done1); 196. glo(1); 197. mklev(); 198. u.ux = xupstair; 199. u.uy = yupstair; 200. (void) inshop(); 201. setsee(); 202. flags.botlx = 1; 203. makedog(); 204. seemons(); 205. docrt(); 206. pickup(); 207. read_engr_at(u.ux,u.uy); /* superfluous ? */ 208. flags.move = 1; 209. flags.cbreak = ON; 210. flags.echo = OFF; 211. } 212. setftty(); 213. #ifdef TRACK 214. initrack(); 215. #endif TRACK 216. for(;;) { 217. if(flags.move) { 218. #ifdef TRACK 219. settrack(); 220. #endif TRACK 221. if(moves%2 == 0 || 222. (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) { 223. extern struct monst *makemon(); 224. movemon(); 225. if(!rn2(70)) 226. (void) makemon((struct permonst *)0, 0, 0); 227. } 228. if(Glib) glibr(); 229. timeout(); 230. ++moves; 231. if(u.uhp < 1) { 232. pline("You die..."); 233. done("died"); 234. } 235. if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50){ 236. wailmsg = moves; 237. if(u.uhp == 1) 238. pline("You hear the wailing of the Banshee..."); 239. else 240. pline("You hear the howling of the CwnAnnwn..."); 241. } 242. if(u.uhp < u.uhpmax) { 243. if(u.ulevel > 9) { 244. if(Regeneration || !(moves%3)) { 245. flags.botl = 1; 246. u.uhp += rnd((int) u.ulevel-9); 247. if(u.uhp > u.uhpmax) 248. u.uhp = u.uhpmax; 249. } 250. } else if(Regeneration || 251. (!(moves%(22-u.ulevel*2)))) { 252. flags.botl = 1; 253. u.uhp++; 254. } 255. } 256. if(Teleportation && !rn2(85)) tele(); 257. if(Searching && multi >= 0) (void) dosearch(); 258. gethungry(); 259. invault(); 260. } 261. if(multi < 0) { 262. if(!++multi){ 263. pline(nomovemsg ? nomovemsg : 264. "You can move again."); 265. nomovemsg = 0; 266. if(afternmv) (*afternmv)(); 267. afternmv = 0; 268. } 269. } 270. flags.move = 1; 271. find_ac(); 272. #ifndef QUEST 273. if(!flags.mv || Blind) 274. #endif QUEST 275. { 276. seeobjs(); 277. seemons(); 278. nscr(); 279. } 280. if(flags.botl || flags.botlx) bot(); 281. if(multi > 0) { 282. #ifdef QUEST 283. if(flags.run >= 4) finddir(); 284. #endif QUEST 285. lookaround(); 286. if(!multi) { /* lookaround may clear multi */ 287. flags.move = 0; 288. continue; 289. } 290. if(flags.mv) { 291. if(multi<COLNO && !--multi) 292. flags.mv = flags.run = 0; 293. domove(); 294. } else { 295. --multi; 296. rhack(save_cm); 297. } 298. } else if(multi == 0) 299. rhack((char *) 0); 300. } 301. } 302. 303. lockcheck() 304. { 305. extern int errno; 306. register int i, fd; 307. 308. /* we ignore QUIT and INT at this point */ 309. if (link(perm,safelock) == -1) 310. error("Cannot link safelock. (Try again or rm safelock.)"); 311. 312. for(i = 0; i < locknum; i++) { 313. lock[0]= 'a' + i; 314. if((fd = open(lock,0)) == -1) { 315. if(errno == ENOENT) goto gotlock; /* no such file */ 316. (void) unlink(safelock); 317. error("Cannot open %s", lock); 318. } 319. (void) close(fd); 320. } 321. (void) unlink(safelock); 322. error("Too many hacks running now."); 323. gotlock: 324. fd = creat(lock,FMASK); 325. if(fd == -1) { 326. error("cannot creat lock file."); 327. } else { 328. int pid; 329. 330. pid = getpid(); 331. if(write(fd, (char *) &pid, 2) != 2){ 332. error("cannot write lock"); 333. } 334. if(close(fd) == -1){ 335. error("cannot close lock"); 336. } 337. } 338. if(unlink(safelock) == -1){ 339. error("Cannot unlink safelock"); 340. } 341. } 342. 343. /*VARARGS1*/ 344. error(s,a1,a2,a3,a4) char *s,*a1,*a2,*a3,*a4; { 345. printf("Error: "); 346. printf(s,a1,a2,a3,a4); 347. (void) putchar('\n'); 348. exit(1); 349. } 350. 351. glo(foo) 352. register foo; 353. { 354. /* construct the string xlock.n */ 355. register char *tf; 356. 357. tf = lock; 358. while(*tf && *tf!='.') tf++; 359. (void) sprintf(tf, ".%d", foo); 360. } 361. 362. /* 363. * plname is filled either by an option (-u Player or -uPlayer) or 364. * explicitly (-w implies wizard) or by askname. 365. * It may still contain a suffix denoting pl_character. 366. */ 367. askname(){ 368. register int c,ct; 369. printf("\nWho are you? "); 370. ct = 0; 371. while((c = getchar()) != '\n'){ 372. if(c == EOF) error("End of input\n"); 373. if(c != '-') 374. if(c < 'A' || (c > 'Z' && c < 'a') || c > 'z') c = '_'; 375. if(ct < sizeof(plname)-1) plname[ct++] = c; 376. } 377. plname[ct] = 0; 378. if(ct == 0) askname(); 379. #ifdef QUEST 380. else printf("Hello %s, welcome to quest!\n", plname); 381. #else 382. else printf("Hello %s, welcome to hack!\n", plname); 383. #endif QUEST 384. } 385. 386. impossible(){ 387. pline("Program in disorder - perhaps you'd better Quit"); 388. } 389. 390. #ifdef NEWS 391. int stopnews; 392. 393. stopnws(){ 394. (void) signal(SIGINT, SIG_IGN); 395. stopnews++; 396. } 397. 398. outnews(fd) int fd; { 399. int (*prevsig)(); 400. char ch; 401. prevsig = signal(SIGINT, stopnws); 402. while(!stopnews && read(fd,&ch,1) == 1) 403. (void) putchar(ch); 404. (void) putchar('\n'); 405. (void) fflush(stdout); 406. (void) close(fd); 407. (void) signal(SIGINT, prevsig); 408. /* See whether we will ask TSKCFW: he might have told us already */ 409. if(!stopnews && pl_character[0]) 410. getret(); 411. } 412. #endif NEWS 413. 414. chdirx(dir) char *dir; { 415. if(chdir(dir) < 0) { 416. perror(dir); 417. error("Cannot chdir to %s.", dir); 418. } 419. }