ftp.nice.ch/pub/next/unix/games/nethack.3.0.N.bs.tar.gz#/PubDomain/Games/HACK/others/pcmain.c

This is pcmain.c in view mode; [Download] [Up]

/*	SCCS Id: @(#)pcmain.c	3.0	90/01/19
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed.  See license for details. */
/* main.c - PC, ST, and Amiga NetHack */
#include "hack.h"

#ifndef NO_SIGNAL
#include <signal.h>
#endif
#include <ctype.h>
#ifdef DGK
#ifndef AMIGA
#include <sys\stat.h>
#endif
#endif
#ifdef MACOS
extern WindowPtr	HackWindow;
extern short *switches;
extern short macflags;
pascal boolean FDECL(startDlogFProc, (DialogPtr, EventRecord *, short *));
#define msmsg mprintf
#endif

#if !defined(MACOS) && !defined(LATTICE)
char orgdir[PATHLEN];
#endif
char SAVEF[FILENAME];
#ifdef MSDOS
char SAVEP[FILENAME];
#endif

const char *hname = "NetHack";	/* used for syntax messages */
#if !defined(AMIGA) && !defined(MACOS)
char obuf[BUFSIZ];	/* BUFSIZ is defined in stdio.h */
#endif
int hackpid;		/* not used anymore, but kept in for save files */

#if defined(DGK)
struct finfo	zfinfo = ZFINFO;
int i;
#endif /* DGK */

#ifdef __TURBOC__	/* tell Turbo C to make a bigger stack */
extern unsigned _stklen = 0x2000;	/* 8K */
extern unsigned char _osmajor;
#endif

#ifdef TOS
extern long compiletime;
boolean run_from_desktop = TRUE;	/* should we pause before exiting?? */
# ifdef __GNUC__
long _stksize = 16*1024;
# endif
#endif

#ifdef MACOS
#  ifdef AZTEC
#define OMASK	O_RDONLY
#  else
#define OMASK	(O_RDONLY | O_BINARY )
#  endif
# else
#define OMASK	O_RDONLY
#endif

#ifdef MACOS
Boolean justscores;
#endif

#ifdef AMIGA_WBENCH
extern int FromWBench;
#endif

const char *classes = "ABCEHKPRSTVW";

int
main(argc,argv)
int argc;
char *argv[];
{
	extern int x_maze_max, y_maze_max;
	register int fd;
	register char *dir;
#ifndef AMIGA
	int (*funcp)();
#endif
#ifdef TOS
	long clock;
# ifdef __GNUC__
	extern int _unixmode;
	_unixmode = 0;
# endif
#endif
#ifdef __TURBOC__
	if (_osmajor >= 3) hname = argv[0];	/* DOS 3.0+ */
#endif
#ifdef TOS
	if (*argv[0]) {			/* only a CLI can give us argv[0] */
		hname = argv[0];
		run_from_desktop = FALSE;
	}
#endif
#ifdef MACOS
	AppFile	theFile;
	short	message,numFiles;
	SFReply	reply;

	initterm(24,80);
	ObscureCursor();
# ifdef SMALLDATA
	init_decl();
# endif
	/* user might have started up with a save file, so check */
	CountAppFiles(&message,&numFiles);
	if (!message && numFiles) {
		message = 1;

		while(message <= numFiles) {
			GetAppFiles(message,&theFile);
			ClrAppFiles(message);
			if ((theFile.fType == SAVE_TYPE)||(theFile.fType == EXPLORE_TYPE))
				break;
			message++;
		}
		if ((theFile.fType == SAVE_TYPE)||(theFile.fType == EXPLORE_TYPE)) {
			(void)strncpy(SAVEF, (char *)&theFile.fName[1],
						(int)theFile.fName[0]);
			(void)strncpy(plname, (char *)&theFile.fName[1],
						(int)theFile.fName[0]);
			SetVol(0,theFile.vRefNum);
			SAVEF[(int)theFile.fName[0]] = '\0';
			numFiles = 1;
		} else
			numFiles = 0;
	}
	switches = (short *)malloc((NROFOBJECTS+2) * sizeof(long));
	for (fd = 0; fd < (NROFOBJECTS + 2); fd++)
		switches[fd] = fd;
#endif


	/*
	 *  Initialize screen I/O before anything is displayed.
	 *
	 *  startup() must be called before initoptions()
	 *    due to ordering of graphics settings
	 *  and before error(), due to use of termcap strings.
	 */
	gettty();
#if !defined(AMIGA) && !defined(MACOS)
	setbuf(stdout,obuf);
#endif
	startup();
#if !defined(AMIGA) && !defined(MACOS)
	/* Save current directory and make sure it gets restored when
	 * the game is exited.
	 */
	if (getcwd(orgdir, sizeof orgdir) == NULL)
		error("NetHack: current directory path too long");
	funcp = (int (*)())exit; /* Kludge to get around LINT_ARGS of signal. */
# ifndef NO_SIGNAL
	signal(SIGINT, (SIG_RET_TYPE) funcp);	/* restore original directory */
# endif
#endif /* AMIGA || MACOS */

#ifndef MACOS
	if ((dir = getenv("HACKDIR")) != NULL) {
		Strcpy(hackdir, dir);
# ifdef CHDIR
		chdirx (dir, 1);
# endif
	}
#if defined(AMIGA) && defined(CHDIR)
	/*
	 * If we're dealing with workbench, change the directory.  Otherwise
	 * we could get "Insert disk in drive 0" messages. (Must be done
	 * before initoptions())....
	 */
	if(argc == 0)
		chdirx(HACKDIR, 1);
#endif

# if defined(DGK)
	/* zero "fileinfo" array to prevent crashes on level change */
	for (i = 0 ; i <= MAXLEVEL; i++) {
		fileinfo[i] = zfinfo;
	}
# endif /* DGK */

	initoptions();
#ifdef AMIGA_WBENCH
	ami_wbench_init(argc,argv);
#endif
# if defined(TOS) && defined(TEXTCOLOR)
	if (flags.IBMBIOS && flags.use_color)
		set_colors();
# endif
	if (!hackdir[0])
#if !defined(LATTICE) && !defined(AMIGA)
		Strcpy(hackdir, orgdir);
#else
		Strcpy(hackdir, HACKDIR);
#endif
	if(argc > 1) {
	    if (!strncmp(argv[1], "-d", 2)) {
		argc--;
		argv++;
		dir = argv[0]+2;
		if(*dir == '=' || *dir == ':') dir++;
		if(!*dir && argc > 1) {
			argc--;
			argv++;
			dir = argv[0];
		}
		if(!*dir)
		    error("Flag -d must be followed by a directory name.");
		Strcpy(hackdir, dir);
	    } else

	/*
	 * Now we know the directory containing 'record' and
	 * may do a prscore().
	 */
	    if (!strncmp(argv[1], "-s", 2)) {
# ifdef CHDIR
		chdirx(hackdir,0);
# endif
		prscore(argc, argv);
		exit(0);
	    }
	}
#else
	initoptions();
#endif	/* MACOS /* */

	/*
	 * It seems you really want to play.
	 */
	setrandom();
	cls();
#ifdef TOS
	if ((unsigned long)time(&clock) < (unsigned long)compiletime)
		error("Your clock is incorrectly set!");
#endif
	u.uhp = 1;	/* prevent RIP on early quits */
	u.ux = FAR;	/* prevent nscr() */

	/*
	 * Find the creation date of this game,
	 * so as to avoid restoring outdated savefiles.
	 */
	/* gethdate(hname); */

	/*
	 * We cannot do chdir earlier, otherwise gethdate will fail.
	 */
#ifdef CHDIR
	chdirx(hackdir,1);
#endif

#ifndef MACOS
	/*
	 * Process options.
	 */
	while(argc > 1 && argv[1][0] == '-'){
		argv++;
		argc--;
		switch(argv[0][1]){
#if defined(WIZARD) || defined(EXPLORE_MODE)
# ifndef EXPLORE_MODE
		case 'X':
# endif
		case 'D':
# ifdef WIZARD
			/* Must have "name" set correctly by NETHACK.CNF,
			 * NETHACKOPTIONS, or -u
			 * before this flag to enter wizard mode. */
#  ifdef KR1ED
			if(!strcmp(plname, WIZARD_NAME)) {
#  else
			if(!strcmp(plname, WIZARD)) {
#  endif
				wizard = TRUE;
				break;
			}
			/* otherwise fall thru to discover */
# endif
# ifdef EXPLORE_MODE
		case 'X':
			discover = TRUE;
# endif
			break;
#endif
#ifdef NEWS
		case 'n':
			flags.nonews = TRUE;
			break;
#endif
		case 'u':
			if(argv[0][2])
			  (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
			else if(argc > 1) {
			  argc--;
			  argv++;
			  (void) strncpy(plname, argv[0], sizeof(plname)-1);
			} else
				Printf("Player name expected after -u\n");
			break;
#ifdef DGK
		/* Player doesn't want to use a RAM disk
		 */
		case 'r':
			ramdisk = FALSE;
			break;
#endif
		default:
			if (index(classes, toupper(argv[0][1]))) {
				/* allow -T for Tourist, etc. */
				(void) strncpy(pl_character, argv[0]+1,
					       sizeof(pl_character)-1);
				break;
			} else Printf("\nUnknown switch: %s\n", argv[0]);
		case '?':
Printf("\nUsage: %s [-d dir] -s [-[%s]] [maxrank] [name]...", hname, classes);
Printf("\n       or");
Printf("\n       %s [-d dir] [-u name] [-[%s]]", hname, classes);
#if defined(WIZARD) || defined(EXPLORE_MODE)
			Printf(" [-[DX]]");
#endif
#ifdef NEWS
			Printf(" [-n]");
#endif
#ifdef DGK
			Printf(" [-r]");
#endif
			putchar('\n');
			return 0;
		}
	}
#ifdef AMIGA_WBENCH
	ami_wbench_args();
#endif
#ifdef DGK
	set_lock_and_bones();
	copybones(FROMPERM);
#endif
#ifdef WIZARD
	if (wizard)
		Strcpy(plname, "wizard");
	else
#endif
	if (!*plname)
		askname();
	plnamesuffix();		/* strip suffix from name; calls askname() */
				/* again if suffix was whole name */
				/* accepts any suffix */
#ifndef DGK
	Strcpy(lock,plname);
	Strcat(lock,".99");
#endif
#endif /* MACOS */
	start_screen();

	/*
	 * Initialisation of the boundaries of the mazes
	 * Both boundaries have to be even.
	 */

	x_maze_max = COLNO-1;
	if (x_maze_max % 2)
		x_maze_max--;
	y_maze_max = ROWNO-1;
	if (y_maze_max % 2)
		y_maze_max--;

	/* initialize static monster strength array */
	init_monstr();
#ifdef MACOS
	if (!numFiles) {
		askname();
		if(justscores){
			prscore(1,&classes);
			exit(0);
		}
#endif
#if defined(AMIGA) || defined(MACOS)
# ifdef AMIGA_WBENCH
	if(!FromWBench)
# endif
	(void) strncat(SAVEF, plname, 31-4);
#else
	{
		int ix = strlen(SAVEF);
		(void)strncat(SAVEF, plname, 8);
		regularize(SAVEF+ix);
	}
#endif
#ifndef MACOS
# ifdef AMIGA_WBENCH
	if(!FromWBench)
# endif
	Strcat(SAVEF, ".sav");
#else
	}
	Strcpy(lock,plname);
	Strcat(lock,".99");
#endif
	cls();
	if (
#ifdef DGK
# ifdef AMIGA_WBENCH
	    (FromWBench?1:saveDiskPrompt(1)) &&
# else
	    saveDiskPrompt(1) &&
# endif
#endif /* DGK */
#ifdef AMIGA_WBENCH
	    ((fd=ami_wbench_getsave(OMASK)) >=0) &&
#else
	    ((fd = open(SAVEF, OMASK)) >= 0) &&
#endif
	   /* if not up-to-date, quietly unlink file via false condition */
	   (uptodate(fd) || unlink(SAVEF) == 666)) {
#ifdef WIZARD
		/* Since wizard is actually flags.debug, restoring might
		 * overwrite it.
		 */
		boolean remember_wiz_mode = wizard;
#endif
#ifndef NO_SIGNAL
		(void) signal(SIGINT, (SIG_RET_TYPE) done1);
#endif
		pline("Restoring save file...");
		(void) fflush(stdout);
		if(!dorecover(fd))
			goto not_recovered;
#ifdef WIZARD
		if(!wizard && remember_wiz_mode) wizard = TRUE;
#endif
		pline("Hello %s, welcome to NetHack!", plname);
		/* get shopkeeper set properly if restore is in shop */
		(void) inshop();
#ifdef EXPLORE_MODE
		if (discover)
			You("are in non-scoring discovery mode.");
#endif
#if defined(EXPLORE_MODE) || defined(WIZARD)
		if (discover || wizard) {
			pline("Do you want to keep the save file? ");
			if(yn() == 'n'){
				(void) unlink(SAVEF);
#ifdef AMIGA_WBENCH
				ami_wbench_unlink(SAVEF);
#endif
			}
		}
#endif
		flags.move = 0;
	} else {
not_recovered:
		newgame();
		/* give welcome message before pickup messages */
		pline("Hello %s, welcome to NetHack!", plname);
#ifdef EXPLORE_MODE
		if (discover)
			You("are in non-scoring discovery mode.");
#endif
		flags.move = 0;
		set_wear();
		pickup(1);
		read_engr_at(u.ux,u.uy);
	}
	
#ifdef MACOS
	{
		short	i;
		MenuHandle	theMenu;
		Rect	screen;
		
		theMenu = GetMHandle(appleMenu);
		EnableItem(theMenu, 0);
		EnableItem(theMenu, 1);
		theMenu = GetMHandle(fileMenu);
		EnableItem(theMenu,0);
		for (i = inventMenu;i <= extendMenu; i++) {
			theMenu = GetMHandle(i);
			EnableItem(theMenu, 0);
		}
		DrawMenuBar();
		macflags |= fDoUpdate;
		SetPort(HackWindow);
		screen = HackWindow->portRect;
		ValidRect(&screen);
		
	}
#endif
			
	flags.moonphase = phase_of_the_moon();
	if(flags.moonphase == FULL_MOON) {
		You("are lucky!  Full moon tonight.");
		if(!u.uluck) change_luck(1);
	} else if(flags.moonphase == NEW_MOON) {
		pline("Be careful!  New moon tonight.");
	}

	initrack();
#ifndef NO_SIGNAL
	(void) signal(SIGINT, SIG_IGN);
#endif
#ifdef OS2
	gettty(); /* somehow ctrl-P gets turned back on during startup ... */
#endif

	moveloop();
#ifdef MACOS 
	/* Help for Mac compilers */
	free_decl();
#endif
	return 0;
}


/*
 * plname is filled either by an option (-u Player  or  -uPlayer) or
 * explicitly (by being the wizard) or by askname.
 * It may still contain a suffix denoting pl_character.
 */
void
askname() {
#ifndef MACOS
	register int c, ct;

	Printf("\nWho are you? ");
	(void) fflush(stdout);
	ct = 0;
	while((c = Getchar()) != '\n') {
		if(c == EOF) error("End of input\n");
		/* some people get confused when their erase char is not ^H */
		if(c == '\b') {
			if(ct) {
				ct--;
#ifdef MSDOS
				msmsg("\b \b");
#endif
			}
			continue;
		}
		if(ct < sizeof(plname)-1) {
#if defined(MSDOS)
			msmsg("%c", c);
#endif
			plname[ct++] = c;
		}
	}
	plname[ct] = 0;
	if(ct == 0) askname();
}
#else /* MACOS */
/* Macintosh startup Dialog written by Andy Swanson 10/20/89
		modified for to include a few more options 12/17/89 */
	DialogPtr asknameDlog;
	DialogTHndl	th, centreDlgBox();
	int kind;
	Rect box;
	Handle knob;
	Boolean Done;
	int chtype = 0,Hit,i;
	Str255 ptemp;
	char *p;
#define OK 1
#define NAME_TEXT 3
#define RADIO_MIN 5
#define RADIO_MAX 17
#define CAVEPERSON 7
#define CLERGY 11
#define VALKYRIE 15
#define ANY 17
#define WIZ 18
#define EXP 19
#define FEM 20
#define NEWS_BOX 21
#define SCORES 22
#define setCheckBox(a,b,c) {GetDItem(a,b,&kind,&knob,&box);SetCtlValue(knob,c?1:0);}
#define changeRadio(a,b,c) {setCheckBox(a,b,FALSE); setCheckBox(a,c,TRUE);}
#define Disable(b) {GetDItem(asknameDlog,b,&kind,&knob,&box);HiliteControl(knob,255);}
#define Enable(b) {GetDItem(asknameDlog,b,&kind,&knob,&box);HiliteControl(knob,0);}
#define Hide(b)  {GetDItem(asknameDlog,b,&kind,&knob,&box);HideControl(knob);\
			SetDItem(asknameDlog,b,kind+128,knob,&box);}
	justscores = FALSE;
	if(p=strrchr((char *)plname, '-')){
		*p = 0;
		if(('a'<= p[1]) && ('z'>= p[1]))p[1] += 'A' - 'a';
		pl_character[0] = p[1];
		pl_character[1] = 0;
		if(chtype = (int)index(classes,p[1]))
			chtype -= (int)(classes)-1;
		if(p[1] == 'V')
			flags.female = TRUE;
	}
	if(chtype != 0) chtype += 4;
	else chtype = 17;
#ifdef THINKC4
	if(!*plname && (p = getlogin()))
		(void) strncpy((char *)&plname,p,sizeof(plname)-1);
#endif
	th = centreDlgBox(131, FALSE);
	
	asknameDlog = GetNewDialog(131,0,-1);
	
	ReleaseResource((Handle)th);
	if(*plname){
		GetDItem(asknameDlog,NAME_TEXT,&kind,&knob,&box);
		strncpy((char*)ptemp,(char*)&plname,255);
		CtoPstr((char*)ptemp);
		SetIText(knob,ptemp);
	}
	GetDItem(asknameDlog,chtype,&kind,&knob,&box);
	SetCtlValue(knob,1);
	if(flags.female){
		setCheckBox(asknameDlog,FEM,TRUE);
		changeDgenders(asknameDlog,TRUE);
	}
#ifdef NEWS
	setCheckBox(asknameDlog,NEWS_BOX,!flags.nonews);
#else
	Hide(NEWS_BOX);
#endif
#ifdef WIZARD
	wizard = FALSE;
# ifdef KR1ED
	if (strcmp(plname,WIZARD_NAME)) {
# else
	if (strcmp(plname,WIZARD)) {
# endif
#else
	{
#endif
		Hide(WIZ);
	}
#ifdef EXPLORE_MODE
	setCheckBox(asknameDlog,EXP,discover);
#else
		Hide(EXP);
#endif
	SelIText(asknameDlog, NAME_TEXT, 0, 32767);
	ShowWindow(asknameDlog);
	Done = FALSE;
	while (!Done){
		ModalDialog(startDlogFProc, &Hit);
		if(Hit == OK){
			Done = TRUE;
			GetDItem(asknameDlog,NAME_TEXT,&kind,&knob,&box);
			GetIText(knob,&ptemp);
			PtoCstr((char*)ptemp);
			(void) strncpy((char*)&plname,(char*)ptemp,sizeof(plname)-1);
			pl_character[0]=classes[chtype-5];
			pl_character[1]=0;
			HideWindow(asknameDlog);
		} else if((Hit >= RADIO_MIN) && (Hit <= RADIO_MAX)){
			extern int lastDlgBut;
			
			changeRadio(asknameDlog,chtype,Hit);
			lastDlgBut = chtype = Hit;
			if ((chtype == VALKYRIE) && !flags.female) {
				flags.female = TRUE;
				setCheckBox(asknameDlog,FEM,flags.female);
				changeDgenders(asknameDlog,TRUE);
			}
		} else if(Hit == WIZ) {
			wizard = !wizard;
			setCheckBox(asknameDlog,WIZ,wizard);
		} else if(Hit == EXP) {
			discover = !discover;
			setCheckBox(asknameDlog,EXP,discover);
		} else if(Hit == FEM) {
			flags.female = !flags.female;
			setCheckBox(asknameDlog,FEM,flags.female);
			if(chtype == VALKYRIE) {
				chtype = ANY;
				changeRadio(asknameDlog,VALKYRIE,ANY);
			}
			changeDgenders(asknameDlog,flags.female);
		} else if(Hit == NEWS_BOX) {
			flags.nonews = !flags.nonews;
			setCheckBox(asknameDlog,NEWS_BOX,!flags.nonews);
		} else if(Hit == SCORES) {
			justscores = !justscores;
			setCheckBox(asknameDlog,SCORES,justscores);
			if(justscores) for (i=RADIO_MIN;i<SCORES;i++) {
				Disable(i);
				}
			else for (i=RADIO_MIN;i<SCORES;i++)
				Enable(i);
		}
	}
	DisposDialog(asknameDlog);
}


#define RADIO_STRING "ABCEHKPRSTVWL"
int	lastDlgBut = ANY;

/* The filterProc for handling character selection from keyboard
   by h+@nada.kth.se                                             */
pascal boolean
startDlogFProc(theDialog, theEvent, itemHit)
DialogPtr theDialog;
EventRecord * theEvent;
short * itemHit;
{
	int x, c;

	if(theEvent->what == keyDown) {
		c = theEvent->message & 0xFF;
#ifdef BETA /* We don't want this is no shipped version */
		if(c == '#') Debugger();
#endif
		if(c == 10 || c == 13 || c == 3) { /* Accept */
			*itemHit = OK;
			return TRUE;
		}
		if(c == '\t' || c == ' ') { /* Select */
			lastDlgBut++;
			if(lastDlgBut > RADIO_MAX) lastDlgBut = RADIO_MIN;
			*itemHit = lastDlgBut;
			return TRUE;
		}
		if(theEvent->modifiers & cmdKey) {
			if(c >= 'a' && c <= 'z') c &= 0x5F; /* Uppercase */
			switch(c) {
			case 'F' :
				*itemHit = FEM;
				return TRUE;
			case 'X' :
				*itemHit = EXP;
				return TRUE;
			case 'N' :
				*itemHit = NEWS_BOX;
				return TRUE;
			case 'J' :
				*itemHit = SCORES;
				return TRUE;
			default :
				for(x=0; RADIO_STRING[x]; x++) {
					if(c == RADIO_STRING[x]) {
						*itemHit = x + RADIO_MIN;
						return TRUE;
					}
				}
			}
			theEvent->what = nullEvent;
		}
	}

	return FALSE;
}


changeDgenders(Dlog,fem)
DialogPtr Dlog;
Boolean fem;
{	int kind;
	Rect box;
	Handle knob;
	Str255 ptemp;
	if(fem){
		GetDItem(Dlog,CAVEPERSON,&kind,&knob,&box);
		strncpy((char*)ptemp,"Cave-Woman",255);
		CtoPstr((char*)ptemp);
		SetCTitle(knob,ptemp);
		GetDItem(Dlog,CLERGY,&kind,&knob,&box);
		strncpy((char*)ptemp,"Priestess",255);
		CtoPstr((char*)ptemp);
		SetCTitle(knob,ptemp);
	} else {
		GetDItem(Dlog,CAVEPERSON,&kind,&knob,&box);
		strncpy((char*)ptemp,"Cave-Man",255);
		CtoPstr((char*)ptemp);
		SetCTitle(knob,ptemp);
		GetDItem(Dlog,CLERGY,&kind,&knob,&box);
		strncpy((char*)ptemp,"Priest",255);
		CtoPstr((char*)ptemp);
		SetCTitle(knob,ptemp);
	}
}
#endif /* MACOS */


#ifdef CHDIR
void
chdirx(dir, wr)
char *dir;
boolean wr;
{
#ifdef AMIGA
	static char thisdir[] = "";
#else
	static char thisdir[] = ".";
#endif
	if(dir && chdir(dir) < 0) {
		error("Cannot chdir to %s.", dir);
	}

	/* Change the default drive as well.
	 */
#ifndef AMIGA
	chdrive(dir);
#endif

	/* warn the player if we can't write the record file */
	/* perhaps we should also test whether . is writable */
	/* unfortunately the access systemcall is worthless */
	if(wr) {
	    register int fd;

	    if(dir == NULL)
		dir = thisdir;
#ifdef OS2_CODEVIEW  /* explicit path on opening for OS/2 */
	    {
	    char tmp[PATHLEN];

	    Strcpy(tmp, dir);
	    append_slash(tmp);
	    Strcat(tmp, RECORD);
	    if((fd = open(tmp, O_RDWR)) < 0) {
#else
	    if((fd = open(RECORD, O_RDWR)) < 0) {
#endif
#ifdef DGK
# ifndef OS2_CODEVIEW
		char tmp[PATHLEN];

		Strcpy(tmp, dir);
		append_slash(tmp);
# endif
		/* try to create empty record */

# ifdef OS2_CODEVIEW
		if((fd = open(tmp, O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) < 0) {
		    msmsg("Warning: cannot write %s\n", tmp);
# else
# ifdef AZTEC_C
		/* Aztec doesn't use the third argument */
		if((fd = open(RECORD, O_CREAT|O_RDWR)) < 0) {
		    msmsg("Warning: cannot write %s%s\n", tmp, RECORD);
# else
  		if((fd = open(RECORD, O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) < 0) {
		    msmsg("Warning: cannot write %s%s\n", tmp, RECORD);
# endif
# endif
		    getreturn("to continue");
		} else
		    (void) close(fd);
#else
		Printf("Warning: cannot write %s/%s", dir, RECORD);
		getret();
#endif
	    } else
		(void) close(fd);
#ifdef OS2_CODEVIEW
	    }
#endif
	}
}
#endif /* CHDIR /**/

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.