Fix:	SE038

Problem:
	File area support has generally been lost in the merge with the 3.3
	codebase (some fragments did survive, and some have already been
	restored in previous fixes). This attempts to restore all the missing
	ones. I have not attempted to review the code to see if 3.3 adds
	any code that needs file area support, or indeed to test the file
	area support code (except when it is disabled).

Compatible with:
	Slash'EM 0.0.5E9 (DOS only)

Author: J. Ali Harlow, ali@avrc.city.ac.uk

Date:	10 Jan 2000

*** doc/window.doc.orig	Mon Jan 10 18:46:34 2000
--- doc/window.doc	Mon Jan 10 18:54:46 2000
***************
*** 172,180 ****
  		   player_selection() offers a Quit option, it is its
  		   responsibility to clean up and terminate the process.
  		   You need to fill in pl_character[0].
  display_file(str, boolean complain)
  		-- Display the file named str.  Complain about missing files
! 		   iff complain is TRUE.
  update_inventory()
  		-- Indicate to the window port that the inventory has been
  		   changed.
--- 172,188 ----
  		   player_selection() offers a Quit option, it is its
  		   responsibility to clean up and terminate the process.
  		   You need to fill in pl_character[0].
+ #ifdef FILE_AREAS
+ display_file(area, str, boolean complain)
+ #else
  display_file(str, boolean complain)
+ #endif
  		-- Display the file named str.  Complain about missing files
! 		   iff complain is TRUE. If FILE_AREAS is defined then the
! 		   file should be found in the named area. Note that vanilla
! 		   does not define FILE_AREAS and therefore window ports
! 		   defined in this way will be compatible with both Slash'EM
! 		   and vanilla NetHack.
  update_inventory()
  		-- Indicate to the window port that the inventory has been
  		   changed.
*** include/extern.h.orig	Mon Jan 10 18:46:36 2000
--- include/extern.h	Mon Jan 10 18:53:37 2000
***************
*** 2005,2010 ****
--- 2005,2020 ----
  # ifdef PORT_HELP
  E void NDECL(port_help);
  # endif
+ #ifdef FILE_AREAS
+ E char *FDECL(make_file_name, (const char *, const char *));
+ E FILE *FDECL(fopen_datafile_area, (const char *,const char *,const char *));
+ E FILE *FDECL(freopen_area, (const char *,const char *,const char *, FILE *));
+ E int FDECL(chmod_area, (const char *, const char *, int));
+ E int FDECL(open_area, (const char *, const char *, int, int));
+ E int FDECL(creat_area, (const char *, const char *, int));
+ E boolean FDECL(lock_file_area, (const char *, const char *,int));
+ E void FDECL(unlock_file_area, (const char *, const char *));
+ #endif
  #endif /* UNIX */
  
  
*** include/global.h.orig	Mon Jan 10 18:46:36 2000
--- include/global.h	Mon Jan 10 18:54:46 2000
***************
*** 34,40 ****
  #define HISTORY		"history"	/* a file giving nethack's history */
  #define HISTORY_AREA	FILE_AREA_SHARE
  #define LICENSE		"license"	/* file with license information */
! #define LICENSE_AREA	FILE_AREA_SHARE
  #define OPTIONFILE	"opthelp"	/* a file explaining runtime options */
  #define OPTIONAREA	FILE_AREA_SHARE
  #define OPTIONS_USED	"options"	/* compile-time options, for #version */
--- 34,40 ----
  #define HISTORY		"history"	/* a file giving nethack's history */
  #define HISTORY_AREA	FILE_AREA_SHARE
  #define LICENSE		"license"	/* file with license information */
! #define LICENSE_AREA	FILE_AREA_DOC
  #define OPTIONFILE	"opthelp"	/* a file explaining runtime options */
  #define OPTIONAREA	FILE_AREA_SHARE
  #define OPTIONS_USED	"options"	/* compile-time options, for #version */
***************
*** 44,50 ****
  #else
  #define GUIDEBOOK       "Guidebook.txt"       /* Nethack Guidebook*/
  #endif
! #define GUIDEBOOK_AREA	FILE_AREA_SHARE
  
  #define LEV_EXT	".lev"		/* extension for special level files */
  
--- 44,50 ----
  #else
  #define GUIDEBOOK       "Guidebook.txt"       /* Nethack Guidebook*/
  #endif
! #define GUIDEBOOK_AREA	FILE_AREA_DOC
  
  #define LEV_EXT	".lev"		/* extension for special level files */
  
***************
*** 195,200 ****
--- 195,225 ----
  
  #ifdef WIN32
  #include "ntconf.h"
+ #endif
+ 
+ #ifndef FILE_AREAS
+ 
+ #define fopen_datafile_area(area, filename, mode) fopen_datafile(filename, mode)
+ #define lock_file_area(area, filename, retryct) lock_file(filename, retryct)
+ #define unlock_file_area(area, filename) unlock_file(filename)
+ #define dlb_fopen_area(area, name, mode) dlb_fopen(name, mode)
+ 
+ /*
+  * ALI
+  *
+  * By defining these, functions can pass them around even though they're
+  * not actually used. This can make the code easier to read at the cost
+  * of some efficiency. Given the high overhead of dealing with files anyway,
+  * this is often a good trade-off.
+  */
+ 
+ #define FILE_AREA_VAR		NULL
+ #define FILE_AREA_SAVE		NULL
+ #define FILE_AREA_LEVL		NULL
+ #define FILE_AREA_BONES		NULL
+ #define FILE_AREA_SHARE		NULL
+ #define FILE_AREA_UNSHARE	NULL
+ 
  #endif
  
  #ifndef FILE_AREAS
*** include/qt_win.h.orig	Mon Jan 10 18:46:37 2000
--- include/qt_win.h	Mon Jan 10 18:54:46 2000
***************
*** 747,753 ****
--- 747,757 ----
  	static void qt_destroy_nhwindow(winid wid);
  	static void qt_curs(winid wid, int x, int y);
  	static void qt_putstr(winid wid, int attr, const char *text);
+ #ifdef FILE_AREAS
+ 	static void qt_display_file(const char *filearea, const char *filename, BOOLEAN_P must_exist);
+ #else
  	static void qt_display_file(const char *filename, BOOLEAN_P must_exist);
+ #endif
  	static void qt_start_menu(winid wid);
  	static void qt_add_menu(winid wid, int glyph,
  		const ANY_P * identifier, CHAR_P ch, CHAR_P gch, int attr,
*** include/trampoli.h.orig	Mon Jan 10 18:46:37 2000
--- include/trampoli.h	Mon Jan 10 18:54:46 2000
***************
*** 313,319 ****
--- 313,323 ----
  #define tty_destroy_nhwindow(x)		tty_destroy_nhwindow_(x)
  #define tty_curs(x,y,z)			tty_curs_(x,y,z)
  #define tty_putstr(x,y,z)		tty_putstr_(x,y,z)
+ #ifdef FILE_AREAS
+ #define tty_display_file(x,y,z)		tty_display_file_(x,y,z)
+ #else
  #define tty_display_file(x,y)		tty_display_file_(x,y)
+ #endif
  #define tty_start_menu(x)		tty_start_menu_(x)
  #define tty_add_menu(a,b,c,d,e,f,g,h)	tty_add_menu_(a,b,c,d,e,f,g,h)
  #define tty_end_menu(a,b)		tty_end_menu_(a,b)
*** include/unixconf.h.orig	Mon Jan 10 18:47:32 2000
--- include/unixconf.h	Mon Jan 10 18:54:46 2000
***************
*** 90,96 ****
   *
   * File areas can be used to place different Slash'EM files in different
   * directories. This is necessary to comply with Linux's FSSTD 1.2 and its
!  * replacement FS 2.0. Currently, these are only implemented for UNIX, but
   * other ports could follow suit by including similar defines in their port
   * specific config files and implementing the relevent functions.
   *
--- 90,96 ----
   *
   * File areas can be used to place different Slash'EM files in different
   * directories. This is necessary to comply with Linux's FSSTD 1.2 and its
!  * replacement FHS 2.0. Currently, these are only implemented for UNIX, but
   * other ports could follow suit by including similar defines in their port
   * specific config files and implementing the relevent functions.
   *
***************
*** 108,113 ****
--- 108,114 ----
   * FILE_AREA_VAR	For other files which may be modified by Slash'EM
   * FILE_AREA_SHARE	For read-only, architechure independent, files 
   * FILE_AREA_UNSHARE	For read-only, architechure dependent, files 
+  * FILE_AREA_DOC	For human-readable documentation
   */
  
  /* #define FILE_AREAS		/* Use file areas */
***************
*** 124,129 ****
--- 125,131 ----
  /* #define FILE_AREA_SAVE	"/var/lib/games/slashem/save/"  /* */
  /* #define FILE_AREA_SHARE	"/usr/lib/games/slashem/"	/* */
  /* #define FILE_AREA_UNSHARE	"/usr/lib/games/slashem/"	/* */
+ /* #define FILE_AREA_DOC	"/usr/doc/slashem/"	/* */
  
  /*
   * File areas compatible with FHS 2.0
***************
*** 133,138 ****
--- 135,141 ----
  #define FILE_AREA_SAVE		"/var/games/slashem/save/"      /* */
  #define FILE_AREA_SHARE		"/usr/share/games/slashem/"	/* */
  #define FILE_AREA_UNSHARE	"/usr/lib/games/slashem/"	/* */
+ #define FILE_AREA_DOC		"/usr/share/doc/slashem/"	/* */
  
  #define FILE_AREA_BONES		FILE_AREA_VAR
  #define FILE_AREA_LEVL		FILE_AREA_VAR
*** include/winX.h.orig	Mon Jan 10 18:46:37 2000
--- include/winX.h	Mon Jan 10 18:54:46 2000
***************
*** 368,374 ****
--- 368,378 ----
  E void FDECL(X11_destroy_nhwindow, (winid));
  E void FDECL(X11_curs, (winid,int,int));
  E void FDECL(X11_putstr, (winid, int, const char *));
+ #ifdef FILE_AREAS
+ E void FDECL(X11_display_file, (const char *, const char *, BOOLEAN_P));
+ #else
  E void FDECL(X11_display_file, (const char *, BOOLEAN_P));
+ #endif
  E void FDECL(X11_start_menu, (winid));
  E void FDECL(X11_add_menu, (winid,int,const ANY_P *,
  			CHAR_P, CHAR_P, int, const char *, BOOLEAN_P));
*** include/winprocs.h.orig	Mon Jan 10 18:46:37 2000
--- include/winprocs.h	Mon Jan 10 18:54:46 2000
***************
*** 20,26 ****
--- 20,30 ----
      void FDECL((*win_destroy_nhwindow), (winid));
      void FDECL((*win_curs), (winid,int,int));
      void FDECL((*win_putstr), (winid, int, const char *));
+ #ifdef FILE_AREAS
+     void FDECL((*win_display_file), (const char *, const char *, BOOLEAN_P));
+ #else
      void FDECL((*win_display_file), (const char *, BOOLEAN_P));
+ #endif
      void FDECL((*win_start_menu), (winid));
      void FDECL((*win_add_menu), (winid,int,const ANY_P *,
  		CHAR_P,CHAR_P,int,const char *, BOOLEAN_P));
***************
*** 85,90 ****
--- 89,99 ----
  #define curs (*windowprocs.win_curs)
  #define putstr (*windowprocs.win_putstr)
  #define display_file (*windowprocs.win_display_file)
+ #ifdef FILE_AREAS
+ #define display_file_area(area,file,complain) display_file(area,file,complain)
+ #else
+ #define display_file_area(area,file,complain) display_file(file,complain)
+ #endif
  #define start_menu (*windowprocs.win_start_menu)
  #define add_menu (*windowprocs.win_add_menu)
  #define end_menu (*windowprocs.win_end_menu)
*** include/wintty.h.orig	Mon Jan 10 18:46:37 2000
--- include/wintty.h	Mon Jan 10 18:54:46 2000
***************
*** 180,186 ****
--- 180,190 ----
  E void FDECL(tty_destroy_nhwindow, (winid));
  E void FDECL(tty_curs, (winid,int,int));
  E void FDECL(tty_putstr, (winid, int, const char *));
+ #ifdef FILE_AREAS
+ E void FDECL(tty_display_file, (const char *, const char *, BOOLEAN_P));
+ #else
  E void FDECL(tty_display_file, (const char *, BOOLEAN_P));
+ #endif
  E void FDECL(tty_start_menu, (winid));
  E void FDECL(tty_add_menu, (winid,int,const ANY_P *,
  			CHAR_P,CHAR_P,int,const char *, BOOLEAN_P));
*** src/allmain.c.orig	Mon Jan 10 18:46:38 2000
--- src/allmain.c	Mon Jan 10 18:54:46 2000
***************
*** 491,497 ****
  	(void) signal(SIGINT, (SIG_RET_TYPE) done1);
  #endif
  #ifdef NEWS
! 	if(iflags.news) display_file(NEWS, FALSE);
  #endif
  
  	load_qtlist();  /* load up the quest text info */
--- 491,497 ----
  	(void) signal(SIGINT, (SIG_RET_TYPE) done1);
  #endif
  #ifdef NEWS
! 	if(iflags.news) display_file_area(NEWS_AREA, NEWS, FALSE);
  #endif
  
  	load_qtlist();  /* load up the quest text info */
*** src/dlb.c.orig	Mon Jan 10 18:46:39 2000
--- src/dlb.c	Mon Jan 10 19:09:52 2000
***************
*** 29,35 ****
--- 29,44 ----
  } dlb_procs_t;
  
  /* without extern.h via hack.h, these haven't been declared for us */
+ #ifdef FILE_AREAS
+ extern FILE *FDECL(fopen_datafile_area, (const char *,const char *,
+                                                             const char *));
+ #else
+ /*
+  * If FILE_AREAS is not defined, then fopen_datafile_area
+  * is a macro defined in terms of fopen_datafile.
+  */
  extern FILE *FDECL(fopen_datafile, (const char *,const char *));
+ #endif
  
  #ifdef DLBLIB
  /*
***************
*** 65,71 ****
  static long FDECL(lib_dlb_ftell,(dlb *));
  
  /* not static because shared with dlb_main.c */
! boolean FDECL(open_library,(const char *lib_name, library *lp));
  void FDECL(close_library,(library *lp));
  
  /* without extern.h via hack.h, these haven't been declared for us */
--- 74,81 ----
  static long FDECL(lib_dlb_ftell,(dlb *));
  
  /* not static because shared with dlb_main.c */
! boolean FDECL(open_library,(const char *lib_area, const char *lib_name,
! 								library *lp));
  void FDECL(close_library,(library *lp));
  
  /* without extern.h via hack.h, these haven't been declared for us */
***************
*** 193,205 ****
   * structure.  Return TRUE if successful, FALSE otherwise.
   */
  boolean
! open_library(lib_name, lp)
!     const char *lib_name;
      library *lp;
  {
      boolean status = FALSE;
  
!     lp->fdata = fopen_datafile(lib_name, RDBMODE);
      if (lp->fdata) {
  	if (readlibdir(lp)) {
  	    status = TRUE;
--- 203,215 ----
   * structure.  Return TRUE if successful, FALSE otherwise.
   */
  boolean
! open_library(lib_area, lib_name, lp)
!     const char *lib_area, *lib_name;
      library *lp;
  {
      boolean status = FALSE;
  
!     lp->fdata = fopen_datafile_area(lib_area, lib_name, RDBMODE);
      if (lp->fdata) {
  	if (readlibdir(lp)) {
  	    status = TRUE;
***************
*** 233,241 ****
      (void) memset((char *)&dlb_libs[0], 0, sizeof(dlb_libs));
  
      /* To open more than one library, add open library calls here. */
!     if (!open_library(DLBFILE, &dlb_libs[0])) return FALSE;
  #ifdef DLBFILE2
!     if (!open_library(DLBFILE2, &dlb_libs[1]))  {
  	close_library(&dlb_libs[0]);
  	return FALSE;
      }
--- 243,251 ----
      (void) memset((char *)&dlb_libs[0], 0, sizeof(dlb_libs));
  
      /* To open more than one library, add open library calls here. */
!     if (!open_library(DLBAREA, DLBFILE, &dlb_libs[0])) return FALSE;
  #ifdef DLBFILE2
!     if (!open_library(DLBAREA2, DLBFILE2, &dlb_libs[1]))  {
  	close_library(&dlb_libs[0]);
  	return FALSE;
      }
***************
*** 441,449 ****
--- 451,465 ----
      }
  }
  
+ 
  dlb *
+ #ifndef FILE_AREAS
  dlb_fopen(name, mode)
      const char *name, *mode;
+ #else
+ dlb_fopen_area(area, name, mode)
+     const char *area, *name, *mode;
+ #endif
  {
      FILE *fp;
      dlb *dp;
***************
*** 453,459 ****
--- 469,479 ----
      dp = (dlb *) alloc(sizeof(dlb));
      if (do_dlb_fopen(dp, name, mode))
      	dp->fp = (FILE *) 0;
+ #ifndef FILE_AREAS
      else if ((fp = fopen_datafile(name, mode)) != 0)
+ #else
+     else if ((fp = fopen_datafile_area(area, name, mode)) != 0)
+ #endif
  	dp->fp = fp;
      else {
  	/* can't find anything */
*** src/files.c.orig	Mon Jan 10 18:46:40 2000
--- src/files.c	Mon Jan 10 18:54:55 2000
***************
*** 1582,1588 ****
--- 1584,1594 ----
  #endif
  {
  #if defined(UNIX) || defined(VMS)
+ # ifdef FILE_AREAS
+ 	int fd = open_area(RECORD_AREA, RECORD, O_RDWR, 0);
+ # else
  	int fd = open(RECORD, O_RDWR, 0);
+ # endif
  
  	if (fd >= 0) {
  # ifdef VMS     /* must be stream-lf to use UPDATE_RECORD_IN_PLACE */
***************
*** 1594,1604 ****
--- 1600,1618 ----
  		}
  # endif
  	    (void) close(fd);   /* RECORD is accessible */
+ #  ifdef FILE_AREAS
+ 	} else if ((fd = open_area(RECORD_AREA, RECORD, O_CREAT|O_RDWR, FCMASK)) >= 0) {
+ #  else
  	} else if ((fd = open(RECORD, O_CREAT|O_RDWR, FCMASK)) >= 0) {
+ #  endif
  	    (void) close(fd);   /* RECORD newly created */
  # if defined(VMS) && !defined(SECURE)
  	    /* Re-protect RECORD with world:read+write+execute+delete access. */
+ #  ifdef FILE_AREAS
+ 	    (void) chmod_area(RECORD_AREA, RECORD, FCMASK | 007);
+ #  else
  	    (void) chmod(RECORD, FCMASK | 007); /* allow everyone full access */
+ #  endif
  # endif /* VMS && !SECURE */
  	} else {
  	    raw_printf("Warning: cannot write scoreboard file %s/%s",
***************
*** 1621,1629 ****
  	Strcpy(tmp, RECORD);
  # endif
  
  	if ((fd = open(tmp, O_RDWR)) < 0) {
  	    /* try to create empty record */
! # if defined(AZTEC_C) || defined(_DCC)
  	    /* Aztec doesn't use the third argument */
  	    /* DICE doesn't like it */
  	    if ((fd = open(tmp, O_CREAT|O_RDWR)) < 0) {
--- 1635,1650 ----
  	Strcpy(tmp, RECORD);
  # endif
  
+ # ifdef FILE_AREAS
+ 	if ((fd = open_area(RECORD_AREA, tmp, O_RDWR)) < 0) {
+ # else
  	if ((fd = open(tmp, O_RDWR)) < 0) {
+ # endif
  	    /* try to create empty record */
! # if defined(FILE_AREAS)
! 	    if ((fd = open_area(RECORD_AREA, tmp, O_CREAT|O_RDWR,
! 	      S_IREAD|S_IWRITE)) < 0) {
! # elif defined(AZTEC_C) || defined(_DCC)
  	    /* Aztec doesn't use the third argument */
  	    /* DICE doesn't like it */
  	    if ((fd = open(tmp, O_CREAT|O_RDWR)) < 0) {
*** src/gypsy.c.orig	Mon Jan 10 18:46:40 2000
--- src/gypsy.c	Mon Jan 10 18:54:46 2000
***************
*** 833,839 ****
  			tarocchi(mtmp);
  			break;
  		case '?':
! 			display_file("gypsy.txt", TRUE);
  			break;
  	}
  
--- 833,839 ----
  			tarocchi(mtmp);
  			break;
  		case '?':
! 			display_file_area(FILE_AREA_SHARE, "gypsy.txt", TRUE);
  			break;
  	}
  
*** src/mail.c.orig	Mon Jan 10 18:46:40 2000
--- src/mail.c	Mon Jan 10 18:54:46 2000
***************
*** 523,529 ****
  	}
  #  else
  #   ifndef AMS				/* AMS mailboxes are directories */
! 	display_file(mailbox, TRUE);
  #   endif /* AMS */
  #  endif /* DEF_MAILREADER */
  
--- 523,529 ----
  	}
  #  else
  #   ifndef AMS				/* AMS mailboxes are directories */
! 	display_file_area(NULL, mailbox, TRUE);
  #   endif /* AMS */
  #  endif /* DEF_MAILREADER */
  
*** src/pager.c.orig	Mon Jan 10 18:46:41 2000
--- src/pager.c	Mon Jan 10 18:54:46 2000
***************
*** 847,866 ****
  
  	if (help_menu(&sel)) {
  		switch (sel) {
! 			case  0:  display_file(HELP, TRUE);  break;
! 			case  1:  display_file(SHELP, TRUE);  break;
  			case  2:  (void) dohistory();  break;
  			case  3:  (void) dowhatis();  break;
  			case  4:  (void) dowhatdoes();  break;
  			case  5:  option_help();  break;
! 			case  6:  display_file(OPTIONFILE, TRUE);  break;
  			case  7:  (void) doextlist();  break;
! 			case  8:  display_file(LICENSE, TRUE);  break;
  /*WAC add guidebook.*/
!                         case  9:  display_file(GUIDEBOOK, TRUE);  break;
  #ifdef WIZARD
                          /* handle slot 10 or 11 */
! 			default: display_file(DEBUGHELP, TRUE);  break;
  #endif
  #ifdef PORT_HELP
  			case PORT_HELP_ID:  port_help();  break;
--- 847,876 ----
  
  	if (help_menu(&sel)) {
  		switch (sel) {
! 			case  0:  display_file_area(HELP_AREA, HELP, TRUE);
! 				  break;
! 			case  1:  display_file_area(SHELP_AREA, SHELP, TRUE);
! 				  break;
  			case  2:  (void) dohistory();  break;
  			case  3:  (void) dowhatis();  break;
  			case  4:  (void) dowhatdoes();  break;
  			case  5:  option_help();  break;
! 			case  6:  display_file_area(OPTIONAREA,
! 				    OPTIONFILE, TRUE);
! 				  break;
  			case  7:  (void) doextlist();  break;
! 			case  8:  display_file_area(LICENSE_AREA,
! 				    LICENSE, TRUE);
! 				  break;
  /*WAC add guidebook.*/
!                         case  9:  display_file_area(GUIDEBOOK_AREA,
! 				    GUIDEBOOK, TRUE);
! 				  break;
  #ifdef WIZARD
                          /* handle slot 10 or 11 */
! 			default:  display_file_area(DEBUGHELP_AREA,
! 				    DEBUGHELP, TRUE);
! 				  break;
  #endif
  #ifdef PORT_HELP
  			case PORT_HELP_ID:  port_help();  break;
***************
*** 873,879 ****
  int
  dohistory()
  {
! 	display_file(HISTORY, TRUE);
  	return 0;
  }
  
--- 883,889 ----
  int
  dohistory()
  {
! 	display_file_area(HISTORY_AREA, HISTORY, TRUE);
  	return 0;
  }
  
*** src/questpgr.c.orig	Mon Jan 10 18:46:41 2000
--- src/questpgr.c	Mon Jan 10 18:54:05 2000
***************
*** 9,14 ****
--- 9,15 ----
  
  #include "qtext.h"
  
+ #define QTEXT_AREA      FILE_AREA_SHARE
  #define QTEXT_FILE	"quest.dat"
  
  /* #define DEBUG */	/* uncomment for debugging */
***************
*** 94,100 ****
  	char	qt_classes[N_HDR][LEN_HDR];
  	long	qt_offsets[N_HDR];
  
! 	msg_file = dlb_fopen(QTEXT_FILE, RDBMODE);
  	if (!msg_file)
  	    panic("\rCANNOT OPEN QUEST TEXT FILE %s.", QTEXT_FILE);
  
--- 95,101 ----
  	char	qt_classes[N_HDR][LEN_HDR];
  	long	qt_offsets[N_HDR];
  
! 	msg_file = dlb_fopen_area(QTEXT_AREA, QTEXT_FILE, RDBMODE);
  	if (!msg_file)
  	    panic("\rCANNOT OPEN QUEST TEXT FILE %s.", QTEXT_FILE);
  
*** src/topten.c.orig	Mon Jan 10 18:46:42 2000
--- src/topten.c	Mon Jan 10 18:54:55 2000
***************
*** 333,346 ****
  #endif
  
  #ifdef LOGFILE		/* used for debugging (who dies of what, where) */
! 	if (lock_file(LOGFILE, 10)) {
! 	    if(!(lfile = fopen_datafile(LOGFILE,"a"))) {
  		HUP raw_print("Cannot open log file!");
  	    } else {
  		writeentry(lfile, t0);
  		(void) fclose(lfile);
  	    }
! 	    unlock_file(LOGFILE);
  	}
  #endif /* LOGFILE */
  
--- 333,346 ----
  #endif
  
  #ifdef LOGFILE		/* used for debugging (who dies of what, where) */
! 	if (lock_file_area(LOGAREA, LOGFILE, 10)) {
! 	    if(!(lfile = fopen_datafile_area(LOGAREA, LOGFILE, "a"))) {
  		HUP raw_print("Cannot open log file!");
  	    } else {
  		writeentry(lfile, t0);
  		(void) fclose(lfile);
  	    }
! 	    unlock_file_area(LOGAREA, LOGFILE);
  	}
  #endif /* LOGFILE */
  
***************
*** 356,373 ****
  	    goto showwin;
  	}
  
! 	if (!lock_file(RECORD, 60))
  		goto destroywin;
  
  #ifdef UPDATE_RECORD_IN_PLACE
! 	rfile = fopen_datafile(RECORD, "r+");
  #else
! 	rfile = fopen_datafile(RECORD, "r");
  #endif
  
  	if (!rfile) {
  		HUP raw_print("Cannot open record file!");
! 		unlock_file(RECORD);
  		goto destroywin;
  	}
  
--- 356,373 ----
  	    goto showwin;
  	}
  
! 	if (!lock_file_area(RECORD_AREA, RECORD, 60))
  		goto destroywin;
  
  #ifdef UPDATE_RECORD_IN_PLACE
! 	rfile = fopen_datafile_area(RECORD_AREA, RECORD, "r+");
  #else
! 	rfile = fopen_datafile_area(RECORD_AREA, RECORD, "r");
  #endif
  
  	if (!rfile) {
  		HUP raw_print("Cannot open record file!");
! 		unlock_file_area(RECORD_AREA, RECORD);
  		goto destroywin;
  	}
  
***************
*** 439,447 ****
  				     t0->fpos : final_fpos), SEEK_SET);
  #else
  		(void) fclose(rfile);
! 		if(!(rfile = fopen_datafile(RECORD,"w"))){
  			HUP raw_print("Cannot write record file");
! 			unlock_file(RECORD);
  			free_ttlist(tt_head);
  			goto destroywin;
  		}
--- 439,447 ----
  				     t0->fpos : final_fpos), SEEK_SET);
  #else
  		(void) fclose(rfile);
! 		if(!(rfile = fopen_datafile_area(RECORD_AREA, RECORD, "w"))){
  			HUP raw_print("Cannot write record file");
! 			unlock_file_area(RECORD_AREA, RECORD);
  			free_ttlist(tt_head);
  			goto destroywin;
  		}
***************
*** 517,523 ****
  	}
  #endif	/* UPDATE_RECORD_IN_PLACE */
  	(void) fclose(rfile);
! 	unlock_file(RECORD);
  	free_ttlist(tt_head);
  
    showwin:
--- 517,523 ----
  	}
  #endif	/* UPDATE_RECORD_IN_PLACE */
  	(void) fclose(rfile);
! 	unlock_file_area(RECORD_AREA, RECORD);
  	free_ttlist(tt_head);
  
    showwin:
***************
*** 743,749 ****
  		return;
  	}
  
! 	rfile = fopen_datafile(RECORD, "r");
  	if (!rfile) {
  		raw_print("Cannot open record file!");
  		return;
--- 743,749 ----
  		return;
  	}
  
! 	rfile = fopen_datafile_area(RECORD_AREA, RECORD, "r");
  	if (!rfile) {
  		raw_print("Cannot open record file!");
  		return;
***************
*** 890,896 ****
  
  	if (!otmp) return((struct obj *) 0);
  
! 	rfile = fopen_datafile(RECORD, "r");
  	if (!rfile) {
  		impossible("Cannot open record file!");
  		return (struct obj *)0;
--- 890,896 ----
  
  	if (!otmp) return((struct obj *) 0);
  
! 	rfile = fopen_datafile_area(RECORD_AREA, RECORD, "r");
  	if (!rfile) {
  		impossible("Cannot open record file!");
  		return (struct obj *)0;
*** src/version.c.orig	Mon Jan 10 18:46:42 2000
--- src/version.c	Mon Jan 10 18:54:46 2000
***************
*** 34,40 ****
  int
  doextversion()
  {
! 	display_file(OPTIONS_USED, TRUE);
  	return 0;
  }
  
--- 34,40 ----
  int
  doextversion()
  {
! 	display_file_area(OPTIONS_USED_AREA, OPTIONS_USED, TRUE);
  	return 0;
  }
  
*** sys/share/pcmain.c.orig	Mon Jan 10 18:46:49 2000
--- sys/share/pcmain.c	Mon Jan 10 18:54:46 2000
***************
*** 352,358 ****
  #endif
  #ifdef NEWS
  		if(iflags.news){
! 		    display_file(NEWS, FALSE);
  		    iflags.news = FALSE;
  		}
  #endif
--- 352,358 ----
  #endif
  #ifdef NEWS
  		if(iflags.news){
! 		    display_file_area(NEWS_AREA, NEWS, FALSE);
  		    iflags.news = FALSE;
  		}
  #endif
***************
*** 592,598 ****
  port_help()
  {
      /* display port specific help file */
!     display_file( PORT_HELP, 1 );
  }
  # endif /* MSDOS || WIN32 */
  #endif /* PORT_HELP */
--- 592,598 ----
  port_help()
  {
      /* display port specific help file */
!     display_file_area(FILE_AREA_SHARE, PORT_HELP, 1 );
  }
  # endif /* MSDOS || WIN32 */
  #endif /* PORT_HELP */
*** sys/unix/Makefile.top.orig	Mon Jan 10 18:47:06 2000
--- sys/unix/Makefile.top	Mon Jan 10 18:54:46 2000
***************
*** 41,46 ****
--- 41,47 ----
  FILE_AREA_SAVE = $(GAMEDIR)/save
  FILE_AREA_SHARE = $(GAMEDIR)
  FILE_AREA_UNSHARE = $(GAMEDIR)
+ FILE_AREA_DOC = $(GAMEDIR)
  FILE_AREA_BONES = $(FILE_AREA_VAR)
  FILE_AREA_LEVL = $(FILE_AREA_VAR)
  SHELLDIR = $(PREFIX)/local/bin
***************
*** 50,55 ****
--- 51,57 ----
  # FILE_AREA_SAVE = /var/lib/games/slashem/save
  # FILE_AREA_SHARE = /usr/lib/games/slashem
  # FILE_AREA_UNSHARE = /usr/lib/games/slashem
+ # FILE_AREA_DOC = /usr/doc/slashem
  # FILE_AREA_BONES = $(FILE_AREA_VAR)
  # FILE_AREA_LEVL = $(FILE_AREA_VAR)
  # SHELLDIR = /usr/games
***************
*** 59,64 ****
--- 61,67 ----
  # FILE_AREA_SAVE = /var/games/slashem/save
  # FILE_AREA_SHARE = /usr/share/games/slashem
  # FILE_AREA_UNSHARE = /usr/lib/games/slashem
+ # FILE_AREA_DOC = /usr/share/doc/slashem
  # FILE_AREA_BONES = $(FILE_AREA_VAR)
  # FILE_AREA_LEVL = $(FILE_AREA_VAR)
  # SHELLDIR = /usr/games
***************
*** 97,103 ****
  # end of configuration
  #
  
! DATHELP = help hh cmdhelp history opthelp wizhelp
  
  SPEC_LEVS = asmodeus.lev baalz.lev bigrm-?.lev castle.lev fakewiz?.lev \
  	juiblex.lev knox.lev medusa-?.lev minend-?.lev minefill.lev \
--- 100,106 ----
  # end of configuration
  #
  
! DATHELP = help hh cmdhelp history opthelp wizhelp gypsy.txt
  
  SPEC_LEVS = asmodeus.lev baalz.lev bigrm-?.lev castle.lev fakewiz?.lev \
  	juiblex.lev knox.lev medusa-?.lev minend-?.lev minefill.lev \
***************
*** 111,117 ****
  	tomb.lev yeenoghu.lev frnknstn.lev nightmar.lev
  QUEST_LEVS = ???-goal.lev ???-fil?.lev ???-loca.lev ???-strt.lev
  
! SHARE_DATNODLB = $(CNF_SHARE_DATND) license
  UNSHARE_DATNODLB =
  SHARE_DATDLB = $(DATHELP) $(CNF_SHARE_DATD)
  UNSHARE_DATDLB = dungeon $(SPEC_LEVS) $(QUEST_LEVS)
--- 114,120 ----
  	tomb.lev yeenoghu.lev frnknstn.lev nightmar.lev
  QUEST_LEVS = ???-goal.lev ???-fil?.lev ???-loca.lev ???-strt.lev
  
! SHARE_DATNODLB = $(CNF_SHARE_DATND)
  UNSHARE_DATNODLB =
  SHARE_DATDLB = $(DATHELP) $(CNF_SHARE_DATD)
  UNSHARE_DATDLB = dungeon $(SPEC_LEVS) $(QUEST_LEVS)
***************
*** 196,202 ****
  	  	-e '$$s/.*/nodlb/p' < dat/options` ;	\
  	$(MAKE) dofiles-$${target-nodlb}
  	cp src/$(GAME) $(FILE_AREA_UNSHARE)
! 	cp doc/Guidebook.txt $(FILE_AREA_SHARE)
  #	cp win/Qt/KDE/kslashem.kdelnk $(KDEDIR)/share/applnk/Games
  	-rm -f $(SHELLDIR)/$(GAME)
  	sed -e 's;/usr/games/lib/nethackdir;$(FILE_AREA_UNSHARE);' \
--- 199,205 ----
  	  	-e '$$s/.*/nodlb/p' < dat/options` ;	\
  	$(MAKE) dofiles-$${target-nodlb}
  	cp src/$(GAME) $(FILE_AREA_UNSHARE)
! 	cp license doc/Guidebook.txt $(FILE_AREA_DOC)
  #	cp win/Qt/KDE/kslashem.kdelnk $(KDEDIR)/share/applnk/Games
  	-rm -f $(SHELLDIR)/$(GAME)
  	sed -e 's;/usr/games/lib/nethackdir;$(FILE_AREA_UNSHARE);' \
***************
*** 207,215 ****
  	-( cd $(FILE_AREA_UNSHARE) ; $(CHOWN) $(GAMEUID) $(GAME) ; \
  			$(CHGRP) $(GAMEGRP) $(GAME) )
  	chmod $(GAMEPERM) $(FILE_AREA_UNSHARE)/$(GAME)
! 	$(CHOWN) $(GAMEUID) $(FILE_AREA_SHARE)/Guidebook.txt
! 	$(CHGRP) $(GAMEGRP) $(FILE_AREA_SHARE)/Guidebook.txt
! 	chmod $(FILEPERM) $(FILE_AREA_SHARE)/Guidebook.txt
  	-$(CHOWN) $(GAMEUID) $(SHELLDIR)/$(GAME)
  	$(CHGRP) $(GAMEGRP) $(SHELLDIR)/$(GAME)
  	chmod $(EXEPERM) $(SHELLDIR)/$(GAME)
--- 210,219 ----
  	-( cd $(FILE_AREA_UNSHARE) ; $(CHOWN) $(GAMEUID) $(GAME) ; \
  			$(CHGRP) $(GAMEGRP) $(GAME) )
  	chmod $(GAMEPERM) $(FILE_AREA_UNSHARE)/$(GAME)
! 	-( cd $(FILE_AREA_DOC) ; \
! 			$(CHOWN) $(GAMEUID) license Guidebook.txt ; \
! 			$(CHGRP) $(GAMEGRP) license Guidebook.txt ; \
! 			chmod $(FILEPERM) license Guidebook.txt )
  	-$(CHOWN) $(GAMEUID) $(SHELLDIR)/$(GAME)
  	$(CHGRP) $(GAMEGRP) $(SHELLDIR)/$(GAME)
  	chmod $(EXEPERM) $(SHELLDIR)/$(GAME)
***************
*** 260,267 ****
--- 264,273 ----
  	-mkdir $(SHELLDIR)
  	-rm -rf $(FILE_AREA_VAR) $(FILE_AREA_BONES) $(FILE_AREA_SAVE)
  	-rm -rf $(FILE_AREA_LEVL) $(FILE_AREA_SHARE) $(FILE_AREA_UNSHARE)
+ 	-rm -rf $(FILE_AREA_DOC)
  	-mkdir $(FILE_AREA_VAR) $(FILE_AREA_BONES) $(FILE_AREA_SAVE)
  	-mkdir $(FILE_AREA_LEVL) $(FILE_AREA_SHARE) $(FILE_AREA_UNSHARE)
+ 	-mkdir $(FILE_AREA_DOC)
  	-$(CHOWN) $(GAMEUID) $(FILE_AREA_VAR) $(FILE_AREA_BONES) $(FILE_AREA_SAVE)
  	$(CHGRP) $(GAMEGRP) $(FILE_AREA_VAR) $(FILE_AREA_BONES) $(FILE_AREA_SAVE)
  	chmod $(DIRPERM) $(FILE_AREA_VAR) $(FILE_AREA_BONES) $(FILE_AREA_SAVE)
*** sys/unix/unixmain.c.orig	Mon Jan 10 18:46:50 2000
--- sys/unix/unixmain.c	Mon Jan 10 18:54:46 2000
***************
*** 229,235 ****
  		(void) signal(SIGINT, (SIG_RET_TYPE) done1);
  #ifdef NEWS
  		if(iflags.news) {
! 		    display_file(NEWS, FALSE);
  		    iflags.news = FALSE; /* in case dorecover() fails */
  		}
  #endif
--- 229,235 ----
  		(void) signal(SIGINT, (SIG_RET_TYPE) done1);
  #ifdef NEWS
  		if(iflags.news) {
! 		    display_file_area(NEWS_AREA, NEWS, FALSE);
  		    iflags.news = FALSE; /* in case dorecover() fails */
  		}
  #endif
***************
*** 452,458 ****
  	 * Display unix-specific help.   Just show contents of the helpfile
  	 * named by PORT_HELP.
  	 */
! 	display_file(PORT_HELP, TRUE);
  }
  #endif
  
--- 452,458 ----
  	 * Display unix-specific help.   Just show contents of the helpfile
  	 * named by PORT_HELP.
  	 */
! 	display_file_area(FILE_AREA_SHARE, PORT_HELP, TRUE);
  }
  #endif
  
*** sys/vms/vmsmain.c.orig	Mon Jan 10 18:46:52 2000
--- sys/vms/vmsmain.c	Mon Jan 10 18:54:46 2000
***************
*** 188,194 ****
  		(void) signal(SIGINT, (SIG_RET_TYPE) done1);
  #ifdef NEWS
  		if(iflags.news) {
! 		    display_file(NEWS, FALSE);
  		    iflags.news = FALSE; /* in case dorecover() fails */
  		}
  #endif
--- 188,194 ----
  		(void) signal(SIGINT, (SIG_RET_TYPE) done1);
  #ifdef NEWS
  		if(iflags.news) {
! 		    display_file_area(NEWS_AREA, NEWS, FALSE);
  		    iflags.news = FALSE; /* in case dorecover() fails */
  		}
  #endif
***************
*** 429,435 ****
  	 * Display VMS-specific help.   Just show contents of the helpfile
  	 * named by PORT_HELP.
  	 */
! 	display_file(PORT_HELP, TRUE);
  }
  #endif /* PORT_HELP */
  
--- 429,435 ----
  	 * Display VMS-specific help.   Just show contents of the helpfile
  	 * named by PORT_HELP.
  	 */
! 	display_file_area(FILE_AREA_SHARE, PORT_HELP, TRUE);
  }
  #endif /* PORT_HELP */
  
*** win/Qt/qt_win.cpp.orig	Mon Jan 10 18:46:55 2000
--- win/Qt/qt_win.cpp	Mon Jan 10 18:54:46 2000
***************
*** 2889,2894 ****
--- 2889,2897 ----
  	    le->setGeometry(lb->geometry().right()+margin,lb->geometry().top(),
  		group.width()*2/3,le->height());
  	}
+ #ifdef FILE_AREAS
+     free(tile_file);
+ #endif
  
  	show();
  	char choice=0;
***************
*** 3271,3277 ****
--- 3274,3284 ----
      window->PutStr(attr,text);
  }
  
+ #ifdef FILE_AREAS
+ void NetHackQtBind::qt_display_file(const char *filearea, const char *filename, BOOLEAN_P must_exist)
+ #else
  void NetHackQtBind::qt_display_file(const char *filename, BOOLEAN_P must_exist)
+ #endif
  {
      NetHackQtTextWindow* window=new NetHackQtTextWindow(keybuffer);
      bool complain = FALSE;
***************
*** 3283,3289 ****
  	char *cr;
  
  	window->Clear();
! 	f = dlb_fopen_area(FILE_AREA_SHARE, filename, "r");
  	if (!f) {
  	    complain = must_exist;
  	} else {
--- 3290,3300 ----
  	char *cr;
  
  	window->Clear();
! #ifdef FILE_AREAS
! 	f = dlb_fopen_area(filearea, filename, "r");
! #else
! 	f = dlb_fopen(filename, "r");
! #endif
  	if (!f) {
  	    complain = must_exist;
  	} else {
***************
*** 3304,3310 ****
      QFile file(filename);
  #else
      char *path;
!     path = make_file_name(FILE_AREA_SHARE, filename);
      QFile file(path);
  #endif
  
--- 3315,3321 ----
      QFile file(filename);
  #else
      char *path;
!     path = make_file_name(filearea, filename);
      QFile file(path);
  #endif
  
*** win/Qt/qt_win.h.orig	Mon Jan 10 18:46:55 2000
--- win/Qt/qt_win.h	Mon Jan 10 18:54:46 2000
***************
*** 702,708 ****
--- 702,712 ----
  	static void qt_destroy_nhwindow(winid wid);
  	static void qt_curs(winid wid, int x, int y);
  	static void qt_putstr(winid wid, int attr, const char *text);
+ #ifdef FILE_AREAS
+ 	static void qt_display_file(const char *filearea, const char *filename, BOOLEAN_P must_exist);
+ #else
  	static void qt_display_file(const char *filename, BOOLEAN_P must_exist);
+ #endif
  	static void qt_start_menu(winid wid);
  	static void qt_add_menu(winid wid, int glyph,
  		const ANY_P * identifier, CHAR_P ch, CHAR_P gch, int attr,
*** win/X11/tile2x11.c.orig	Mon Jan 10 18:46:56 2000
--- win/X11/tile2x11.c	Mon Jan 10 18:54:29 2000
***************
*** 191,196 ****
--- 191,227 ----
        fwrite_tile_header_item(header->ntiles,fp);
  }
  
+ /*
+  * ALI
+  *
+  * Architecture independent tile file so that x11tiles can always be
+  * stored in FILE_AREA_SHARE, thus simplifying the configuration.
+  */
+ 
+ static boolean
+ fwrite_tile_header_item(item, fp)
+ long item;
+ FILE *fp;
+ {
+     putc((item>>24)&0xff,fp);
+     putc((item>>16)&0xff,fp);
+     putc((item>>8)&0xff,fp);
+     putc(item&0xff,fp);
+     return !ferror(fp);
+ }
+ 
+ static boolean
+ fwrite_tile_header(header, fp)
+ x11_header *header;
+ FILE *fp;
+ {
+     return fwrite_tile_header_item(header->version,fp) &&
+       fwrite_tile_header_item(header->ncolors,fp) &&
+       fwrite_tile_header_item(header->tile_width,fp) &&
+       fwrite_tile_header_item(header->tile_height,fp) &&
+       fwrite_tile_header_item(header->ntiles,fp);
+ }
+ 
  int
  main(argc, argv)
      int argc;
*** win/X11/winX.c.orig	Mon Jan 10 18:46:56 2000
--- win/X11/winX.c	Mon Jan 10 18:54:46 2000
***************
*** 1283,1289 ****
--- 1283,1294 ----
  }
  
  void
+ #ifdef FILE_AREAS
+ X11_display_file(area, str, complain)
+     const char *area;
+ #else
  X11_display_file(str, complain)
+ #endif
      const char *str;
      boolean complain;
  {
***************
*** 1301,1307 ****
      int charcount;
  
      /* Use the port-independent file opener to see if the file exists. */
!     fp = dlb_fopen_area(FILE_AREA_SHARE, str, RDTMODE);
  
      if (!fp) {
  	if(complain) pline("Cannot open %s.  Sorry.", str);
--- 1306,1316 ----
      int charcount;
  
      /* Use the port-independent file opener to see if the file exists. */
! #ifdef FILE_AREAS
!     fp = dlb_fopen_area(area, str, RDTMODE);
! #else
!     fp = dlb_fopen(str, RDTMODE);
! #endif
  
      if (!fp) {
  	if(complain) pline("Cannot open %s.  Sorry.", str);
***************
*** 1335,1341 ****
      textlines = (char *) alloc((unsigned int) charcount);
      textlines[0] = '\0';
  
!     fp = dlb_fopen_area(FILE_AREA_SHARE, str, RDTMODE);
  
      while (dlb_fgets(line, LLEN, fp)) {
  	(void) strcat(textlines, line);
--- 1344,1354 ----
      textlines = (char *) alloc((unsigned int) charcount);
      textlines[0] = '\0';
  
! #ifdef FILE_AREAS
!     fp = dlb_fopen_area(area, str, RDTMODE);
! #else
!     fp = dlb_fopen(str, RDTMODE);
! #endif
  
      while (dlb_fgets(line, LLEN, fp)) {
  	(void) strcat(textlines, line);
*** win/tty/wintty.c.orig	Mon Jan 10 18:46:54 2000
--- win/tty/wintty.c	Mon Jan 10 18:54:46 2000
***************
*** 1929,1942 ****
--- 1929,1951 ----
  }
  
  void
+ #ifdef FILE_AREAS
+ tty_display_file(farea, fname, complain)
+ const char *farea;
+ #else
  tty_display_file(fname, complain)
+ #endif
  const char *fname;
  boolean complain;
  {
  #ifdef DEF_PAGER			/* this implies that UNIX is defined */
      {
  	/* use external pager; this may give security problems */
+ #ifdef FILE_AREAS
+     register int fd = open_area(farea, fname, 0, 0);
+ #else
  	register int fd = open(fname, 0);
+ #endif
  
  	if(fd < 0) {
  	    if(complain) pline("Cannot open %s.", fname);
***************
*** 1966,1972 ****
  	char *cr;
  
  	tty_clear_nhwindow(WIN_MESSAGE);
! 	f = dlb_fopen(fname, "r");
  	if (!f) {
  	    if(complain) {
  		home();  tty_mark_synch();  tty_raw_print("");
--- 1975,1985 ----
  	char *cr;
  
  	tty_clear_nhwindow(WIN_MESSAGE);
! #ifdef FILE_AREAS
!     f = dlb_fopen_area(farea, fname, "r");
! #else
!     f = dlb_fopen(fname, "r");
! #endif
  	if (!f) {
  	    if(complain) {
  		home();  tty_mark_synch();  tty_raw_print("");
*** win/win32/nhprocs.c.orig	Mon Jan 10 18:46:54 2000
--- win/win32/nhprocs.c	Mon Jan 10 18:54:46 2000
***************
*** 552,558 ****
--- 552,563 ----
  }
  
  void
+ #ifdef FILE_AREAS
+ win32_display_file(farea, fname, complain)
+ const char *farea;
+ #else
  win32_display_file(fname, complain)
+ #endif
  const char *fname;
  boolean complain;
  {
*** win/win32/nhwin32.h.orig	Mon Jan 10 18:46:54 2000
--- win/win32/nhwin32.h	Mon Jan 10 18:54:46 2000
***************
*** 252,258 ****
--- 252,262 ----
  E void FDECL(win32_destroy_nhwindow, (winid));
  E void FDECL(win32_curs, (winid,int,int));
  E void FDECL(win32_putstr, (winid, int, const char *));
+ #ifdef FILE_AREAS
+ E void FDECL(win32_display_file, (const char *, const char *, BOOLEAN_P));
+ #else
  E void FDECL(win32_display_file, (const char *, BOOLEAN_P));
+ #endif
  E void FDECL(win32_start_menu, (winid));
  E void FDECL(win32_add_menu, (winid,int,const ANY_P,
  			CHAR_P,int,const char *, BOOLEAN_P));
