1 /* omega (c) 1987,1988,1989 by Laurence Raphael Brothers */
2 /* file.c */
3 /* functions with file access in them. Also some direct calls to
4 curses functions */
5
6 #ifdef MSDOS_SUPPORTED_ANTIQUE
7 # include "curses.h"
8 #else
9 # ifdef AMIGA
10 # include <curses210.h>
11 # else
12 # ifdef __FreeBSD__
13 # include <ncurses.h>
14 # else
15 # include <curses.h>
16 # endif
17 # endif
18 # include <sys/types.h>
19 # include <unistd.h>
20 # include <sys/file.h>
21 # include <fcntl.h>
22 # include <errno.h>
23 #endif
24
25 #include "glob.h"
26
checkfopen(filestring,optionstring)27 FILE *checkfopen(filestring,optionstring)
28 char *filestring,*optionstring;
29 {
30 FILE *fd;
31 char response;
32
33 change_to_game_perms();
34 fd = fopen(filestring,optionstring);
35 clearmsg();
36 while (fd == NULL) {
37 print3("Warning! Error opening file:");
38 nprint3(filestring);
39 print1(" Abort or Retry? [ar] ");
40 do response = (char) mcigetc();
41 while ((response != 'a') && (response != 'r'));
42 if (response == 'r') fd = fopen(filestring,optionstring);
43 else {
44 print2("Sorry 'bout that.... Saving character, then quitting.");
45 morewait();
46 save(optionp(COMPRESS_OPTION), TRUE);
47 endgraf();
48 exit(0);
49 }
50 }
51 return(fd);
52 }
53
commandlist()54 void commandlist()
55 {
56 strcpy(Str1,Omegalib);
57 if (Current_Environment == E_COUNTRYSIDE)
58 strcat(Str1,"help13.txt");
59 else strcat(Str1,"help12.txt");
60 displayfile(Str1);
61 xredraw();
62 }
63
64
user_intro()65 void user_intro()
66 {
67 strcpy(Str1,Omegalib);
68 strcat(Str1,"intro.txt");
69 displaycryptfile(Str1);
70 xredraw();
71 }
72
show_license()73 void show_license()
74 {
75 strcpy(Str1,Omegalib);
76 strcat(Str1,"license.txt");
77 displayfile(Str1);
78 xredraw();
79 }
80
81
82
abyss_file()83 void abyss_file()
84 {
85 strcpy(Str1,Omegalib);
86 strcat(Str1,"abyss.txt");
87 displaycryptfile(Str1);
88 }
89
90
91
92
inv_help()93 void inv_help()
94 {
95 strcpy(Str1,Omegalib);
96 strcat(Str1,"help3.txt");
97 displayfile(Str1);
98 xredraw();
99 }
100
101
102
combat_help()103 void combat_help()
104 {
105 strcpy(Str1,Omegalib);
106 strcat(Str1,"help5.txt");
107 displayfile(Str1);
108 menuclear();
109 }
110
111
112
113
cityguidefile()114 void cityguidefile()
115 {
116 strcpy(Str1,Omegalib);
117 strcat(Str1,"scroll2.txt");
118 displaycryptfile(Str1);
119 xredraw();
120 }
121
122
wishfile()123 void wishfile()
124 {
125 strcpy(Str1,Omegalib);
126 strcat(Str1,"scroll3.txt");
127 displaycryptfile(Str1);
128 xredraw();
129 }
130
adeptfile()131 void adeptfile()
132 {
133 strcpy(Str1,Omegalib);
134 strcat(Str1,"scroll4.txt");
135 displaycryptfile(Str1);
136 xredraw();
137 }
138
theologyfile()139 void theologyfile()
140 {
141 strcpy(Str1,Omegalib);
142 strcat(Str1,"scroll1.txt");
143 displaycryptfile(Str1);
144 xredraw();
145 }
146
147
showmotd()148 void showmotd()
149 {
150 strcpy(Str1,Omegalib);
151 strcat(Str1,"motd.txt");
152 displayfile(Str1);
153 }
154
155
lock_score_file()156 void lock_score_file()
157 {
158 #ifndef MSDOS
159 int lock, attempts, thispid, lastpid = 0;
160 FILE *lockfile;
161
162 strcpy(Str1,Omegalib);
163 strcat(Str1,"omega.hi.lock");
164 do
165 {
166 lock = open(Str1, O_CREAT|O_EXCL, 0600); /* create lock file */
167 if (lock < 0 && errno == EEXIST)
168 {
169 lockfile = fopen(Str1, "rb");
170 if (lockfile)
171 {
172 fscanf(lockfile, "%d", &thispid);
173 fclose(lockfile);
174 if (thispid != lastpid)
175 attempts = 0;
176 lastpid = thispid;
177 }
178 attempts++;
179 if (attempts > 10) /* assume that lock file has been abandoned */
180 unlink(Str1); /* so we unlink it ourselves - ugly... */
181 else
182 sleep(2);
183 }
184 else if (lock < 0) /* oops - something very wrong */
185 return;
186 } while (lock < 0);
187 sprintf(Str1, "%d", getpid());
188 write(lock, Str1, strlen(Str1));
189 close(lock);
190 #endif
191 }
192
unlock_score_file()193 void unlock_score_file()
194 {
195 #ifndef MSDOS
196 strcpy(Str1,Omegalib);
197 strcat(Str1,"omega.hi.lock");
198 unlink(Str1);
199 #endif
200 }
201
showscores()202 void showscores()
203 {
204 FILE *fd;
205 int i;
206
207 lock_score_file();
208 strcpy(Str1,Omegalib);
209 strcat(Str1,"omega.hi");
210 fd = checkfopen(Str1,"rb");
211 filescanstring(fd,Hiscorer);
212 filescanstring(fd,Hidescrip);
213 fscanf(fd,"%ld %d %d\n",&Hiscore,&Hilevel,&Hibehavior);
214 for(i=1;i<7;i++) {
215 filescanstring(fd,Priest[i]);
216 fscanf(fd,"%d %d\n",&(Priestlevel[i]),&(Priestbehavior[i]));
217 }
218 filescanstring(fd,Shadowlord);
219 fscanf(fd,"%d %d\n",&Shadowlordlevel,&Shadowlordbehavior);
220 filescanstring(fd,Commandant);
221 fscanf(fd,"%d %d\n",&Commandantlevel,&Commandantbehavior);
222 filescanstring(fd,Archmage);
223 fscanf(fd,"%d %d\n",&Archmagelevel,&Archmagebehavior);
224 filescanstring(fd,Prime);
225 fscanf(fd,"%d %d\n",&Primelevel,&Primebehavior);
226 filescanstring(fd,Champion);
227 fscanf(fd,"%d %d\n",&Championlevel,&Championbehavior);
228 filescanstring(fd,Duke);
229 fscanf(fd,"%d %d\n",&Dukelevel,&Dukebehavior);
230 filescanstring(fd,Chaoslord);
231 fscanf(fd,"%d %d %d\n",&Chaoslordlevel,&Chaos,&Chaoslordbehavior);
232 filescanstring(fd,Lawlord);
233 fscanf(fd,"%d %d %d\n",&Lawlordlevel,&Law,&Lawlordbehavior);
234 filescanstring(fd,Justiciar);
235 fscanf(fd,"%d %d\n",&Justiciarlevel,&Justiciarbehavior);
236 fclose(fd);
237 unlock_score_file();
238 clear();
239 printw("High Score: %ld",Hiscore);
240 printw(", by %s (%s)",Hiscorer,levelname(Hilevel));
241 printw("\n%s\n",Hidescrip);
242 printw("\nLord of Chaos: %s (%s)",Chaoslord,levelname(Chaoslordlevel));
243 printw("\nLord of Law: %s (%s)",Lawlord,levelname(Lawlordlevel));
244 printw("\n\nDuke of Rampart: ");
245 printw("%s (%s)",Duke,levelname(Dukelevel));
246 printw("\nJusticiar: ");
247 printw("%s (%s)",Justiciar,levelname(Justiciarlevel));
248 printw("\nCommandant: ");
249 printw("%s (%s)",Commandant,levelname(Commandantlevel));
250 printw("\nChampion: ");
251 printw("%s (%s)",Champion,levelname(Championlevel));
252 printw("\nArchmage: ");
253 printw("%s (%s)",Archmage,levelname(Archmagelevel));
254 printw("\nPrime Sorceror: ");
255 printw("%s (%s)",Prime,levelname(Primelevel));
256 printw("\nShadowlord: ");
257 printw("%s (%s)",Shadowlord,levelname(Shadowlordlevel));
258 printw("\n\nHigh Priests:");
259 printw("\n of Odin: ");
260 printw("%s (%s)",Priest[ODIN],levelname(Priestlevel[ODIN]));
261 printw("\n of Set: ");
262 printw("%s (%s)",Priest[SET],levelname(Priestlevel[SET]));
263 printw("\n of Athena: ");
264 printw("%s (%s)",Priest[ATHENA],levelname(Priestlevel[ATHENA]));
265 printw("\n of Hecate: ");
266 printw("%s (%s)",Priest[HECATE],levelname(Priestlevel[HECATE]));
267 printw("\n of the Lords of Destiny: ");
268 printw("%s (%s)",Priest[DESTINY],levelname(Priestlevel[DESTINY]));
269 printw("\nThe ArchDruid: ");
270 printw("%s (%s)",Priest[DRUID],levelname(Priestlevel[DRUID]));
271 printw("\n\nHit any key to continue.");
272 refresh();
273 wgetch(stdscr);
274 clear_screen();
275 }
276
277 /* Writes a new high-score file, with the nominated npc as whatever it is */
278 /* in this particular game, but the others as they appear in the file. */
save_hiscore_npc(npc)279 void save_hiscore_npc(npc)
280 int npc;
281 {
282 FILE *infile, *outfile;
283 char buffer[80];
284 int i;
285
286 if (gamestatusp(CHEATED))
287 return;
288 lock_score_file();
289 strcpy(Str1,Omegalib);
290 strcat(Str1,"omega.hi");
291 infile = checkfopen(Str1,"rb");
292 strcpy(Str2,Omegalib);
293 #ifdef MSDOS
294 strcat(Str2,"omegahi.new"); /* stupid 8.3 msdos filename limit */
295 #else
296 strcat(Str2,"omega.hi.new");
297 #endif
298 outfile = checkfopen(Str2,"wb");
299 for (i = 0; i < 16; i++) {
300 if (npc == i) {
301 switch (i) {
302 case 0:
303 fprintf(outfile,"%s\n%s\n%ld %d %d\n",Hiscorer, Hidescrip, Hiscore,
304 Hilevel, Hibehavior);
305 break;
306 case 1: case 2: case 3: case 4: case 5: case 6:
307 fprintf(outfile,"%s\n%d %d\n", Priest[i], Priestlevel[i],
308 Priestbehavior[i]);
309 break;
310 case 7:
311 fprintf(outfile,"%s\n%d %d\n", Shadowlord, Shadowlordlevel,
312 Shadowlordbehavior);
313 break;
314 case 8:
315 fprintf(outfile,"%s\n%d %d\n", Commandant, Commandantlevel,
316 Commandantbehavior);
317 break;
318 case 9:
319 fprintf(outfile,"%s\n%d %d\n", Archmage, Archmagelevel,
320 Archmagebehavior);
321 break;
322 case 10:
323 fprintf(outfile,"%s\n%d %d\n", Prime, Primelevel, Primebehavior);
324 break;
325 case 11:
326 fprintf(outfile,"%s\n%d %d\n", Champion, Championlevel,
327 Championbehavior);
328 break;
329 case 12:
330 fprintf(outfile,"%s\n%d %d\n", Duke, Dukelevel, Dukebehavior);
331 break;
332 case 13:
333 fprintf(outfile,"%s\n%d %d %d\n",Chaoslord, Chaoslordlevel, Chaos,
334 Chaoslordbehavior);
335 break;
336 case 14:
337 fprintf(outfile,"%s\n%d %d %d\n", Lawlord, Lawlordlevel, Law,
338 Lawlordbehavior);
339 break;
340 case 15:
341 fprintf(outfile,"%s\n%d %d\n", Justiciar, Justiciarlevel,
342 Justiciarbehavior);
343 break;
344 }
345 }
346 if (i == 0) {
347 fgets(buffer, 80, infile);
348 if (i != npc)
349 fputs(buffer, outfile);
350 }
351 fgets(buffer, 80, infile);
352 if (i != npc)
353 fputs(buffer, outfile);
354 fgets(buffer, 80, infile);
355 if (i != npc)
356 fputs(buffer, outfile);
357 }
358 fclose(infile);
359 fclose(outfile);
360 unlink(Str1);
361 #if defined(MSDOS) || defined(AMIGA)
362 rename(Str2, Str1);
363 #else
364 link(Str2, Str1);
365 unlink(Str2); /* renames, but sys-V doesn't have rename()... */
366 #endif
367 unlock_score_file();
368 }
369
checkhigh(descrip,behavior)370 void checkhigh(descrip,behavior)
371 char *descrip;
372 int behavior;
373 {
374 long points;
375
376 if (FixedPoints > 0) points = FixedPoints;
377 else points = calc_points();
378 if (!gamestatusp(CHEATED)) {
379 if (Hiscore < points) {
380 strcpy(Hiscorer, Player.name);
381 strcpy(Hidescrip, descrip);
382 Hiscore = points;
383 Hilevel = Player.level;
384 Hibehavior = behavior;
385 save_hiscore_npc(0);
386 mprint("Yow! A new high score!");
387 morewait();
388 }
389 if (Player.alignment < Chaos) {
390 strcpy(Chaoslord, Player.name);
391 Chaoslordlevel = Player.level;
392 Chaos = Player.alignment;
393 Chaoslordbehavior = behavior;
394 save_hiscore_npc(13);
395 mprint("Criminy! A new Lord of Chaos!");
396 morewait();
397 }
398 if (Player.alignment > Law) {
399 strcpy(Lawlord, Player.name);
400 Lawlordlevel = Player.level;
401 Law = Player.alignment;
402 Lawlordbehavior = behavior;
403 save_hiscore_npc(14);
404 mprint("Gosh! A new Lord of Law!");
405 morewait();
406 }
407 }
408 }
409
extendlog(descrip,lifestatus)410 void extendlog(descrip,lifestatus)
411 char *descrip;
412 int lifestatus;
413 {
414 FILE *fd;
415 int npcbehavior;
416
417 if ((Player.level > 0) && (! gamestatusp(CHEATED))) {
418 change_to_game_perms();
419 npcbehavior=fixnpc(lifestatus);
420 checkhigh(descrip,npcbehavior);
421 strcpy(Str1,Omegalib);
422 strcat(Str1,"omega.log");
423 fd = checkfopen(Str1,"a");
424 fprintf(fd, " %d %d %d %s\n", lifestatus, Player.level, npcbehavior,
425 Player.name);
426 fclose(fd);
427 }
428 }
429
430
431
432
433
434 #ifndef MSDOS
435 /* reads a string from a file. If it is a line with more than 80 char's,
436 then remainder of line to \n is consumed */
filescanstring(fd,fstr)437 void filescanstring(fd,fstr)
438 FILE *fd;
439 char *fstr;
440 {
441 int i= -1;
442 int byte='x';
443 while ((i<80) && (byte != '\n') && (byte != EOF)) {
444 i++;
445 byte=fgetc(fd);
446 fstr[i] = byte;
447 }
448 if (byte != '\n')
449 while((byte!='\n') && (byte != EOF))
450 byte=fgetc(fd);
451 fstr[i]=0;
452 }
453 #endif
454
455 #ifdef MSDOS
test_file_access(file_name,mode)456 int test_file_access(file_name, mode)
457 char *file_name;
458 char mode;
459 {
460 FILE *fd;
461
462 if (mode == 'r')
463 fd = fopen(file_name, "r");
464 else
465 fd = fopen(file_name, "r+");
466 if (!fd)
467 return 0;
468 fclose(fd);
469 return 1;
470 }
471 #else
test_file_access(file_name,mode)472 int test_file_access(file_name, mode)
473 char *file_name;
474 char mode;
475 {
476 int fd;
477
478 if (mode == 'r')
479 fd = open(file_name, O_RDONLY, 0);
480 else
481 fd = open(file_name, O_RDWR, 0);
482 if (fd < 0)
483 return 0;
484 close(fd);
485 return 1;
486 }
487 #endif
488
489 char *required_file_list[] =
490 {
491 "city.dat", "country.dat", "dlair.dat", "misle.dat", "court.dat",
492 "speak.dat", "temple.dat", "abyss.dat", "village1.dat", "village2.dat",
493 "village3.dat", "village4.dat", "village5.dat", "village6.dat",
494 "home1.dat", "home2.dat", "home3.dat", "arena.dat", "maze1.dat",
495 "maze2.dat", "maze3.dat", "maze4.dat", "omega.hi", "omega.log", "motd.txt",
496 "license.txt", "circle.dat", NULL
497 };
498
499 char *optional_file_list[] =
500 {
501 "help1.txt", "help2.txt", "help3.txt", "help4.txt", "help5.txt",
502 "help6.txt", "help7.txt", "help8.txt", "help9.txt", "help10.txt",
503 "help11.txt", "help12.txt", "help13.txt", "abyss.txt", "scroll1.txt",
504 "scroll2.txt", "scroll3.txt", "scroll4.txt", NULL
505 };
506
507 /* Checks existence of omega data files */
508 /* Returns 1 if OK, 0 if impossible to run, -1 if possible but not OK */
filecheck()509 int filecheck()
510 {
511 int impossible=FALSE,badbutpossible=FALSE;
512 int endpos;
513 int file;
514
515 strcpy(Str1, Omegalib);
516 endpos = strlen(Str1);
517 for (file = 0; required_file_list[file]; file++)
518 {
519 strcpy(&(Str1[endpos]), required_file_list[file]);
520 if ((strcmp(required_file_list[file], "omega.hi") == 0 ||
521 strcmp(required_file_list[file], "omega.log") == 0) &&
522 test_file_access(Str1, 'w') == 0)
523 {
524 impossible = TRUE;
525 printf("\nError! File not appendable or accessible: %s", Str1);
526 }
527 else if (test_file_access(Str1, 'r') == 0)
528 {
529 impossible = TRUE;
530 printf("\nError! File not accessible: %s", Str1);
531 }
532 }
533 for (file = 0; optional_file_list[file]; file++)
534 {
535 strcpy(&(Str1[endpos]), optional_file_list[file]);
536 if (test_file_access(Str1, 'r') == 0)
537 {
538 badbutpossible = TRUE;
539 printf("\nWarning! File not accessible: %s", Str1);
540 }
541 }
542 if (impossible) {
543 printf("\nFurther execution is impossible. Sorry.");
544 if (strcmp(Omegalib, OMEGALIB))
545 printf("\nEnvironment variable OMEGALIB badly set\n");
546 else {
547 printf("\nOMEGALIB may be badly #defined in defs.h\n");
548 #ifndef FIXED_OMEGALIB
549 printf("\nYou can set the environment variable OMEGALIB to\n");
550 printf("the location of the omegalib directory.\n");
551 #endif
552 }
553 return(0);
554 }
555 else if (badbutpossible) {
556 printf("\nFurther execution may cause anomalous behavior.");
557 printf("\nContinue anyhow? [yn] ");
558 if (getchar()=='y') return(-1);
559 else return(0);
560 }
561 else return(1);
562 }
563
564 /* display a file given a string name of file */
displayfile(filestr)565 void displayfile(filestr)
566 char *filestr;
567 {
568 FILE *fd = checkfopen(filestr,"r");
569 int c,d=' ';
570 int x,y;
571 clear();
572 refresh();
573 c = fgetc(fd);
574 while ((c != EOF)&&((char) d != 'q')&&((char) d!=ESCAPE)) {
575 getyx(stdscr,y,x);
576 if (y > ScreenLength) {
577 standout();
578 printw("\n-More-");
579 standend();
580 refresh();
581 d = wgetch(stdscr);
582 clear();
583 }
584 printw("%c",(char) c);
585 c = fgetc(fd);
586 }
587 if (((char) d != 'q')&&((char) d!=ESCAPE)) {
588 standout();
589 printw("\n-Done-");
590 standend();
591 refresh();
592 getch();
593 }
594 clear();
595 refresh();
596 fclose(fd);
597 }
598
599 /* display a file given a string name of file */
displaycryptfile(filestr)600 void displaycryptfile(filestr)
601 char *filestr;
602 {
603 FILE *fd = checkfopen(filestr,"rb");
604 int c,d=' ';
605 int x,y;
606 char key = 100;
607
608 clear();
609 refresh();
610 c = fgetc(fd);
611 while ((c != EOF)&&((char) d != 'q')&&((char) d!=ESCAPE)) {
612 getyx(stdscr,y,x);
613 if (y > ScreenLength) {
614 standout();
615 printw("\n-More-");
616 standend();
617 refresh();
618 d = wgetch(stdscr);
619 clear();
620 }
621 key = ((unsigned char) c)^key;
622 printw("%c", key);
623 c = fgetc(fd);
624 }
625 if (((char) d != 'q')&&((char) d!=ESCAPE)) {
626 standout();
627 printw("\n-Done-");
628 standend();
629 refresh();
630 getch();
631 }
632 clear();
633 refresh();
634 fclose(fd);
635 }
636
637 /* copy a file given a string name of file */
copyfile(srcstr)638 void copyfile(srcstr)
639 char *srcstr;
640 {
641 char deststr[80];
642 char buffer[STRING_LEN];
643 FILE *in, *out;
644
645 print1("Enter name of file to create: ");
646 strcpy(deststr,msgscanstring());
647 if (strlen(deststr) == 0) {
648 print2("Aborting...");
649 morewait();
650 return;
651 }
652 in = checkfopen(srcstr, "rb");
653 change_to_user_perms();
654 out = fopen(deststr, "wb");
655 if (!out) {
656 sprintf(buffer, "Unable to write to file %s - Aborting.", deststr);
657 print2(buffer);
658 change_to_game_perms();
659 morewait();
660 fclose(in);
661 return;
662 }
663 print2("Copying file....");
664 while (fgets(buffer, STRING_LEN, in))
665 fputs(buffer, out);
666 fclose(in);
667 fclose(out);
668 change_to_game_perms();
669 print3("Done.");
670 }
671
672