[comp.emacs] Some MircoEMACS 3.10 fixes for System V

linwood@b11.ingr.com (Linwood Varney) (06/13/89)

Hello.

I am sending some diffs that I made after getting 3.10 running on our
version of System V.3.  V.3 does the directory routines a little
differently than V.2 did, and our version happens to support BSD job
control. 

I had a problem with the first version emacs that supported typeahead.
I made some modifications to the typeahead routines using termio instead
of fcntl.  It seemed to fix the problem.  The problem then is you were
always in polling mode, so emacs would be constantly looping, not very
nice on a multi-tasking machine.  With this release of emacs (3.10),
the fcntl approach did not loop continuously, but if you typed fast,
it would drop characters.  I put my termio stuff in, and it still
dropped characters, so the problem may lie elsewhere.  If I find something,
I will let you know.

Ok, now the diffs...

	display.c
		Modifed the mlwrite() routine to use unix variable
		arguments (if defined in estruct.h).  The processor
		that we are running on passes the first 2 arguments
		to every function in a register, so you can not even
		assume stack order!
	unix.c
		In the typeahead function, the line with the read
		under USG came with funny character in the ARC file,
		the word kbdq (the k is messed up).

		Had a problem initially compliling the file under
		System V.3.1 (only file not to compile!).  I had
		to change somethings for the directory routines.
		V.3 has native BSD directory routines, some of the
		variable names though have been changed.

		I then took this to my V.2 machine.  As with the V.3.1
		version, there is not a file called /usr/include/ndir.h
		V.2 though does not have native directory routines.
		I stole ndir.c and ndir.h from the 2.11 news software,
		I hacked a little out of it.   All that needs to change
		for V.2 unix is that <ndir.h> to change to "ndir.h", and
		add ndir.[co] to the makefile.  I am also including those
		in case you want to through them in.  You might want to
		check with Rick Adams, uunet!rick, if these can be given
		away.  I am almost postive they are.

		To get around the subtle differences between System V.2
		and System V.3, I took out the traditional USG define
		and put 2 defines in its place: SYSV2 and SYSV3.  If either
		of those are set, I set USG.  Only where there are differences,
		mostly directory stuff, do I use SYSV2 or SYSV3, in most
		cases USG will work.

		I also took the job control support out of the #if BSD
		and made it a separate option.  This is mainly for versions
		of unix that have job control that are not BSD.
		This could probably made simpler if you were to include
		sys/signal.h on all unix machines and do an #ifdef SIGTSTP,
		but I did not want to include a .h file in a .h file.
		Also the way I did it, JOBCTRL is only on if you define
		JOBCTRL, so maybe it should always say "#if JOBCTRL | BSD",
		or if BSD is set turn on JOBCTRL.

		Fixed a problem in spawn where the [End] message would not
		appear.  This problem was twofold.  First the ttcol variable
		was reset by TTopen, therefore not printing [End] at all,
		and the TTflush call was not performed, so [End] came out
		after a key was entered.

		Filename completion did not work if the file was in the
		current directory, and was not proceeded be a "./".  I
		changed opendir to open "." if the path was NULL.
	input.c
		Added support in the complete function for ~ expansion
		of home directories on unix machines.  I added Shell
		variable expansion at the begining of the line too.
	edef.h
		I changed the default value of $ssave to be FALSE.  This
		caused many problems with changing permissions and ownership.
		A better fix would be to stat the file before saving, and
		do a chown/chgrp/chmod back to the orginal.
	ebind.h
		Modified #if BSD to #if JOBCTRL 
	efunc.h
		Modified #if BSD to #if JOBCTRL 
	estruct.h
		Added #define JOBCTRL and #define VA_ARGS, and changed
		USG to SYSV2 and SYSV3
	ndir.h
		Directory routines for V.2 machines, from 2.11B News software.
	ndir.c
		Directory routines for V.2 machines, from 2.11B News software.

Ok, now the diffs...  Really...

---------------------------------!CUT HERE!--------------------------------

#!/bin/sh
# run this thru sh, e.g. sh file
PATH=:/bin:/usr/bin; export PATH
echo extracting display.diff
sed 's/^X//' <<'!END OF FILE!' >display.diff
X*** orig/display.c	Mon Apr 24 15:17:47 1989
X--- display.c	Wed Apr 26 02:48:07 1989
X***************
X*** 11,16 ****
X--- 11,19 ----
X  #include	"etype.h"
X  #include	"edef.h"
X  #include	"elang.h"
X+ #if VA_ARGS
X+ #include	<varargs.h>
X+ #endif
X  
X  typedef struct	VIDEO {
X  	int	v_flag; 		/* Flags */
X***************
X*** 1091,1104 ****
X  #define	ADJUST(ptr, dtype)	ptr += sizeof(dtype)
X  #endif
X  
X  CDECL NEAR mlwrite(fmt, arg)
X  
X  char *fmt;	/* format string for output */
X  char *arg;	/* pointer to first argument to print */
X  
X  {
X- 	register int c; 	/* current char in format string */
X  	register char *ap;	/* ptr to current data field */
X  
X  	/* if we are not currently echoing on the command line, abort this */
X  	if (discmd == FALSE)
X--- 1094,1115 ----
X  #define	ADJUST(ptr, dtype)	ptr += sizeof(dtype)
X  #endif
X  
X+ #if VA_ARGS
X+ CDECL NEAR mlwrite(va_alist)
X+ va_dcl
X+ {
X+ 	va_list ap;
X+ 	char *fmt;
X+ #else
X  CDECL NEAR mlwrite(fmt, arg)
X  
X  char *fmt;	/* format string for output */
X  char *arg;	/* pointer to first argument to print */
X  
X  {
X  	register char *ap;	/* ptr to current data field */
X+ #endif
X+ 	register int c;		/* current char in format string */
X  
X  	/* if we are not currently echoing on the command line, abort this */
X  	if (discmd == FALSE)
X***************
X*** 1116,1124 ****
X  		TTflush();
X  	}
X  
X  	movecursor(term.t_nrow, 0);
X!  	lastptr = &lastmesg[0];		/* setup to record message */
X  	ap = (char *) &arg;
X  	while ((c = *fmt++) != 0) {
X  		if (c != '%') {
X  			mlout(c);
X--- 1127,1141 ----
X  		TTflush();
X  	}
X  
X+ #if VA_ARGS
X+ 	va_start(ap);
X+ 	fmt = va_arg(ap, char *);
X+ #endif
X  	movecursor(term.t_nrow, 0);
X! #if !VA_ARGS
X  	ap = (char *) &arg;
X+ #endif
X+  	lastptr = &lastmesg[0];		/* setup to record message */
X  	while ((c = *fmt++) != 0) {
X  		if (c != '%') {
X  			mlout(c);
X***************
X*** 1127,1159 ****
X--- 1144,1200 ----
X  			c = *fmt++;
X  			switch (c) {
X  				case 'd':
X+ #if VA_ARGS
X+ 					mlputi(va_arg(ap, int), 10);
X+ #else
X  					mlputi(*(int *)ap, 10);
X  			                ADJUST(ap, int);
X+ #endif
X  					break;
X  
X  				case 'o':
X+ #if VA_ARGS
X+ 					mlputi(va_arg(ap, int), 8);
X+ #else
X  					mlputi(*(int *)ap,  8);
X  					ADJUST(ap, int);
X+ #endif
X  					break;
X  
X  				case 'x':
X+ #if VA_ARGS
X+ 					mlputi(va_arg(ap, int), 16);
X+ #else
X  					mlputi(*(int *)ap, 16);
X  					ADJUST(ap, int);
X+ #endif
X  					break;
X  
X  				case 'D':
X+ #if VA_ARGS
X+ 					mlputli(va_arg(ap, long), 10);
X+ #else
X  					mlputli(*(long *)ap, 10);
X  					ADJUST(ap, long);
X+ #endif
X  					break;
X  
X  				case 's':
X+ #if VA_ARGS
X+ 					mlputs(va_arg(ap, char *));
X+ #else
X  					mlputs(*(char **)ap);
X  					ADJUST(ap, char *);
X+ #endif
X  					break;
X  
X  				case 'f':
X+ #if VA_ARGS
X+ 					mlputf(va_arg(ap, int));
X+ #else
X  					mlputf(*(int *)ap);
X  					ADJUST(ap, int);
X+ #endif
X  					break;
X  
X  				default:
!END OF FILE!
: !CUT HERE!
: run this thru sh, e.g. sh file
PATH=:/bin:/usr/bin; export PATH
echo extracting unix.diff
sed 's/^X//' <<'!END OF FILE!' >unix.diff
X*** orig/unix.c	Mon Apr 24 15:19:04 1989
X--- unix.c	Fri May 12 00:04:23 1989
X***************
X*** 15,27 ****
X  #include	<signal.h>
X  #include	<termio.h>
X  #include	<fcntl.h>
X  #include	<ndir.h>
X  int kbdflgs;			/* saved keyboard fd flags	*/
X  int kbdpoll;			/* in O_NDELAY mode			*/
X  int kbdqp;			/* there is a char in kbdq	*/
X  char kbdq;			/* char we've already read	*/
X  struct	termio	otermio;	/* original terminal characteristics */
X! struct	termio	ntermio;	/* charactoristics to use inside */
X  #endif
X  
X  #if V7 | BSD
X--- 15,40 ----
X  #include	<signal.h>
X  #include	<termio.h>
X  #include	<fcntl.h>
X+ #include	<sys/types.h>
X+ #include	<sys/stat.h>
X+ 
X+ #if	USG
X+ #if	SYSV2
X+ #include	"ndir.h"
X+ #endif
X+ #if	SYSV3
X+ #include	<dirent.h>
X+ #endif
X+ #else
X  #include	<ndir.h>
X+ #endif
X+ 
X  int kbdflgs;			/* saved keyboard fd flags	*/
X  int kbdpoll;			/* in O_NDELAY mode			*/
X  int kbdqp;			/* there is a char in kbdq	*/
X  char kbdq;			/* char we've already read	*/
X  struct	termio	otermio;	/* original terminal characteristics */
X! struct	termio	ntermio;	/* characteristics to use inside */
X  #endif
X  
X  #if V7 | BSD
X***************
X*** 42,53 ****
X  
X  #if BSD
X  #include <sys/ioctl.h>		/* to get at the typeahead */
X- extern	int rtfrmshell();	/* return from suspended shell */
X  #define	TBUFSIZ	128
X  char tobuf[TBUFSIZ];		/* terminal output buffer */
X  #endif
X  #endif
X  
X  #if     V7 | USG | HPUX | SUN | XENIX | BSD
X  #include        <signal.h>
X  extern int vttidy();
X--- 55,69 ----
X  
X  #if BSD
X  #include <sys/ioctl.h>		/* to get at the typeahead */
X  #define	TBUFSIZ	128
X  char tobuf[TBUFSIZ];		/* terminal output buffer */
X  #endif
X  #endif
X  
X+ #if JOBCTRL
X+ int rtfrmshell();		/* return from suspended shell */
X+ #endif
X+ 
X  #if     V7 | USG | HPUX | SUN | XENIX | BSD
X  #include        <signal.h>
X  extern int vttidy();
X***************
X*** 75,80 ****
X--- 91,101 ----
X  	kbdpoll = FALSE;
X  #endif
X  
X+ #if	JOBCTRL
X+ 	signal(SIGTSTP,SIG_DFL);	/* set signals so that we can */
X+ 	signal(SIGCONT,rtfrmshell);	/* suspend & restart emacs */
X+ #endif
X+ 
X  #if     V7 | BSD
X          gtty(0, &ostate);                       /* save old state */
X          gtty(0, &nstate);                       /* get base of new state */
X***************
X*** 87,94 ****
X  	/* provide a smaller terminal output buffer so that
X  	   the type ahead detection works better (more often) */
X  	setbuffer(stdout, &tobuf[0], TBUFSIZ);
X- 	signal(SIGTSTP,SIG_DFL);	/* set signals so that we can */
X- 	signal(SIGCONT,rtfrmshell);	/* suspend & restart emacs */
X  #endif
X  #endif
X  	/* on all screens we are not sure of the initial position
X--- 108,113 ----
X***************
X*** 217,223 ****
X  		if (fcntl(0, F_SETFL, kbdflgs | O_NDELAY) < 0 && kbdpoll)
X  			return(FALSE);
X  		kbdpoll = TRUE;
X! 		kbdqp = (1 == read(0, kbdq, 1));
X  	}
X  	return(kbdqp);
X  #endif
X--- 236,242 ----
X  		if (fcntl(0, F_SETFL, kbdflgs | O_NDELAY) < 0 && kbdpoll)
X  			return(FALSE);
X  		kbdpoll = TRUE;
X! 		kbdqp = (1 == read(0, kbdq, 1));
X  	}
X  	return(kbdqp);
X  #endif
X***************
X*** 259,265 ****
X          return(TRUE);
X  }
X  
X! #if	BSD
X  
X  bktoshell()		/* suspend MicroEMACS and wait to wake up */
X  {
X--- 278,284 ----
X          return(TRUE);
X  }
X  
X! #if	JOBCTRL
X  
X  bktoshell()		/* suspend MicroEMACS and wait to wake up */
X  {
X***************
X*** 299,311 ****
X          TTclose();                              /* stty to old modes    */
X          system(line);
X          TTopen();
X!         TTflush();
X  	/* if we are interactive, pause here */
X  	if (clexec == FALSE) {
X  	        mlputs(TEXT6);
X  /*                     "\r\n\n[End]" */
X          	tgetc();
X          }
X          sgarbf = TRUE;
X          return(TRUE);
X  }
X--- 318,332 ----
X          TTclose();                              /* stty to old modes    */
X          system(line);
X          TTopen();
X!         movecursor(term.t_nrow, 0);             /* Seek to last line.   */
X  	/* if we are interactive, pause here */
X  	if (clexec == FALSE) {
X  	        mlputs(TEXT6);
X  /*                     "\r\n\n[End]" */
X+ 	        TTflush();
X          	tgetc();
X          }
X+ 	TTflush();
X          sgarbf = TRUE;
X          return(TRUE);
X  }
X***************
X*** 333,338 ****
X--- 354,360 ----
X          TTclose();                              /* stty to old modes    */
X          system(line);
X          TTopen();
X+         movecursor(term.t_nrow, 0);             /* Seek to last line.   */
X          mlputs(TEXT188);                        /* Pause.               */
X  /*             "[End]" */
X          TTflush();
X***************
X*** 554,560 ****
X  		closedir(dirptr);
X  		dirptr = NULL;
X  	}
X! 	dirptr = opendir(path);
X  	if (dirptr == NULL)
X  		return(NULL);
X  
X--- 576,585 ----
X  		closedir(dirptr);
X  		dirptr = NULL;
X  	}
X! 	if (path[0])
X! 		dirptr = opendir(path);
X! 	else
X! 		dirptr = opendir(".");
X  	if (dirptr == NULL)
X  		return(NULL);
X  
X***************
X*** 568,574 ****
X--- 593,603 ----
X  char *PASCAL NEAR getnfile()
X  
X  {
X+ #if	SYSV3
X+ 	register struct dirent *dp;	/* directory entry pointer */
X+ #else
X  	register struct direct *dp;	/* directory entry pointer */
X+ #endif
X  	register int index;		/* index into various strings */
X  	struct stat fstat;
X  
!END OF FILE!
: !CUT HERE!
: run this thru sh, e.g. sh file
PATH=:/bin:/usr/bin; export PATH
echo extracting input.diff
sed 's/^X//' <<'!END OF FILE!' >input.diff
X*** orig/input.c	Mon Apr 24 15:18:31 1989
X--- input.c	Sat May 13 08:00:36 1989
X***************
X*** 46,51 ****
X--- 46,59 ----
X  #include	"edef.h"
X  #include	"elang.h"
X  
X+ #if USG | BSD | V7
X+ #include	<pwd.h>
X+ extern	struct passwd *getpwnam();
X+ #if USG
X+ #define	index	strchr
X+ #endif
X+ #endif
X+ 
X  /*
X   * Ask a yes or no question in the message line. Return either TRUE, FALSE, or
X   * ABORT. The ABORT status is returned if the user bumps out of the question
X***************
X*** 209,214 ****
X--- 217,227 ----
X  	register int c;		/* current input character */
X  	int cpos;		/* current column on screen output */
X  	static char buf[NSTRING];/* buffer to hold tentative name */
X+ #if USG | BSD | V7
X+ 	char *home;
X+ 	struct passwd *pwd;
X+ #endif
X+ 
X  #if	COMPLET == 0
X  	int status;
X  #endif
X***************
X*** 306,313 ****
X  			TTflush();
X  			if (buf[cpos - 1] == 0)
X  				return(buf);
X  		} else {
X! 			if (cpos < maxlen && c > ' ') {
X  				buf[cpos++] = c;
X  				mlout(c);
X  				++ttcol;
X--- 319,394 ----
X  			TTflush();
X  			if (buf[cpos - 1] == 0)
X  				return(buf);
X+ #if USG | BSD | V7
X+ 		} else if (c == '/' && type == CMP_FILENAME && buf[0] == '~') {
X+ 			int i;
X+ 
X+ 			if (cpos == 1) {
X+ 				if (home = (char *)getenv("HOME")) {
X+ 
X+ 					mlout('\b');	/* backup over ~ */
X+ 					mlout(' ');
X+ 					mlout('\b');
X+ 					ttcol--;
X+ 					TTflush();
X+ 					strcpy(buf, home);
X+ 					cpos = strlen(buf);
X+ 					buf[cpos++] = '/';
X+ 					for (i = 0; i < cpos; i++) {
X+ 						mlout(buf[i]);
X+ 						ttcol++;
X+ 					}
X+ 					TTflush();
X+ 				} else
X+ 					goto nextc;
X+ 			} else {
X+ 				buf[cpos] = '\0';
X+ 				if (pwd = getpwnam(&buf[1])) {
X+ 					while (cpos != 0) {	/* kill	*/
X+ 						mlout('\b');	/* line	*/
X+ 						mlout(' ');
X+ 						mlout('\b');
X+ 						--cpos;
X+ 						--ttcol;
X+ 					}
X+ 					TTflush();
X+ 					strcpy(buf, pwd->pw_dir);
X+ 					cpos = strlen(buf);
X+ 					buf[cpos++] = '/';
X+ 					for (i = 0; i < cpos; i++) {
X+ 						mlout(buf[i]);
X+ 						ttcol++;
X+ 					}
X+ 					TTflush();
X+ 				} else
X+ 					goto nextc;
X+ 			}
X+ 		} else if (c == '/' && type == CMP_FILENAME && buf[0] == '$') {
X+ 			int i;
X+ 
X+ 			buf[cpos] = '\0';
X+ 			if (home = (char *)getenv(&buf[1])) {
X+ 				while (cpos != 0) {	/* kill	*/
X+ 					mlout('\b');	/* line	*/
X+ 					mlout(' ');
X+ 					mlout('\b');
X+ 					--cpos;
X+ 					--ttcol;
X+ 				}
X+ 				TTflush();
X+ 				strcpy(buf, home);
X+ 				cpos = strlen(buf);
X+ 				buf[cpos++] = '/';
X+ 				for (i = 0; i < cpos; i++) {
X+ 					mlout(buf[i]);
X+ 					ttcol++;
X+ 				}
X+ 				TTflush();
X+ 			} else
X+ 				goto nextc;
X+ #endif
X  		} else {
X! nextc:			if (cpos < maxlen && c > ' ') {
X  				buf[cpos++] = c;
X  				mlout(c);
X  				++ttcol;
!END OF FILE!
: !CUT HERE!
: run this thru sh, e.g. sh file
PATH=:/bin:/usr/bin; export PATH
echo extracting edef.diff
sed 's/^X//' <<'!END OF FILE!' >edef.diff
X*** orig/edef.h	Mon Apr 24 15:17:49 1989
X--- edef.h	Thu May 11 21:54:36 1989
X***************
X*** 41,47 ****
X  NOSHARE int DNEAR sscroll = FALSE;	/* smooth scrolling enabled flag*/
X  NOSHARE int DNEAR hscroll = TRUE;	/* horizontal scrolling flag	*/
X  NOSHARE int DNEAR hjump = 1;		/* horizontal jump size 	*/
X! NOSHARE int DNEAR ssave = TRUE; 	/* safe save flag		*/
X  NOSHARE struct BUFFER *bstore = NULL;	/* buffer to store macro text to*/
X  NOSHARE int DNEAR vtrow = 0;		/* Row location of SW cursor	*/
X  NOSHARE int DNEAR vtcol = 0;		/* Column location of SW cursor */
X--- 41,47 ----
X  NOSHARE int DNEAR sscroll = FALSE;	/* smooth scrolling enabled flag*/
X  NOSHARE int DNEAR hscroll = TRUE;	/* horizontal scrolling flag	*/
X  NOSHARE int DNEAR hjump = 1;		/* horizontal jump size 	*/
X! NOSHARE int DNEAR ssave = FALSE; 	/* safe save flag		*/
X  NOSHARE struct BUFFER *bstore = NULL;	/* buffer to store macro text to*/
X  NOSHARE int DNEAR vtrow = 0;		/* Row location of SW cursor	*/
X  NOSHARE int DNEAR vtcol = 0;		/* Column location of SW cursor */
!END OF FILE!
: !CUT HERE!
: run this thru sh, e.g. sh file
PATH=:/bin:/usr/bin; export PATH
echo extracting ebind.diff
sed 's/^X//' <<'!END OF FILE!' >ebind.diff
X*** orig/ebind.h	Mon Apr 24 15:17:49 1989
X--- ebind.h	Wed Apr 26 00:19:58 1989
X***************
X*** 78,84 ****
X  	{CTLX|'A',		BINDFNC,	setvar},
X  	{CTLX|'B',		BINDFNC,	usebuffer},
X  	{CTLX|'C',		BINDFNC,	spawncli},
X! #if	BSD
X  	{CTLX|'D',		BINDFNC,	bktoshell},
X  #endif
X  	{CTLX|'E',		BINDFNC,	ctlxe},
X--- 78,84 ----
X  	{CTLX|'A',		BINDFNC,	setvar},
X  	{CTLX|'B',		BINDFNC,	usebuffer},
X  	{CTLX|'C',		BINDFNC,	spawncli},
X! #if	JOBCTRL
X  	{CTLX|'D',		BINDFNC,	bktoshell},
X  #endif
X  	{CTLX|'E',		BINDFNC,	ctlxe},
!END OF FILE!
: !CUT HERE!
: run this thru sh, e.g. sh file
PATH=:/bin:/usr/bin; export PATH
echo extracting efunc.diff
sed 's/^X//' <<'!END OF FILE!' >efunc.diff
X*** orig/efunc.h	Mon Apr 24 15:17:50 1989
X--- efunc.h	Wed Apr 26 00:20:03 1989
X***************
X*** 229,235 ****
X  #if	PROC
X  	{"store-procedure",		storeproc},
X  #endif
X! #if	BSD
X  	{"suspend-emacs",		bktoshell},
X  #endif
X  	{"transpose-characters",	twiddle},
X--- 229,235 ----
X  #if	PROC
X  	{"store-procedure",		storeproc},
X  #endif
X! #if	JOBCTRL
X  	{"suspend-emacs",		bktoshell},
X  #endif
X  	{"transpose-characters",	twiddle},
!END OF FILE!
: !CUT HERE!
: run this thru sh, e.g. sh file
PATH=:/bin:/usr/bin; export PATH
echo extracting estruct.diff
sed 's/^X//' <<'!END OF FILE!' >estruct.diff
X*** orig/estruct.h	Mon Apr 24 15:18:15 1989
X--- estruct.h	Wed Apr 26 05:30:53 1989
X***************
X*** 43,49 ****
X  #define OS2	0			/* Microsoft or IBM OS/2	*/
X  #define V7	0			/* V7 UNIX or Coherent or BSD4.2*/ 
X  #define BSD	0			/* UNIX BSD 4.2 and ULTRIX	*/
X! #define USG	0			/* UNIX system V		*/
X  #define	XENIX	0			/* IBM-PC SCO XENIX		*/
X  #define	SUN	0			/* SUN v4.0			*/
X  #define	HPUX	0			/* HPUX HP 9000 minicomputer	*/
X--- 43,50 ----
X  #define OS2	0			/* Microsoft or IBM OS/2	*/
X  #define V7	0			/* V7 UNIX or Coherent or BSD4.2*/ 
X  #define BSD	0			/* UNIX BSD 4.2 and ULTRIX	*/
X! #define SYSV2	0			/* UNIX system V Rel 2		*/
X! #define SYSV3	0			/* UNIX system V Rel 3		*/
X  #define	XENIX	0			/* IBM-PC SCO XENIX		*/
X  #define	SUN	0			/* SUN v4.0			*/
X  #define	HPUX	0			/* HPUX HP 9000 minicomputer	*/
X***************
X*** 52,57 ****
X--- 53,66 ----
X  #define WMCS	0			/* Wicat's MCS			*/
X  #define	AOSVS	0			/* Data General AOS/VS		*/
X  
X+ #if	SYSV2 | SYSV3
X+ #define USG	1
X+ #else
X+ #define	USG	0			
X+ #endif
X+ 
X+ #define	JOBCTRL	0			/* BSD Job Control		*/
X+ 
X  /*	Compiler definitions			*/
X  /*	[Set one of these!!]			*/
X  #define UNIX	0	/* a random UNIX compiler */
X***************
X*** 70,75 ****
X--- 79,85 ----
X  /*      dec vax series stack grows down... got it???        */
X  
X  #define STACK_GROWS_UP  0
X+ #define VA_ARGS 0	/* use variable arguments, don't assume stack!!!  */
X  
X  /*	Debugging options	*/
X  #define	RAMSIZE	0	/* dynamic RAM memory usage tracking */
!END OF FILE!
: !CUT HERE!
: run this thru sh, e.g. sh file
PATH=:/bin:/usr/bin; export PATH
echo extracting ndir.c
sed 's/^X//' <<'!END OF FILE!' >ndir.c
X#include <sys/param.h>
X#include "ndir.h"
X
X/*
X * support for Berkeley directory reading routine on a V7 / V.2 file system
X */
X
Xextern char *malloc();
X
X/*
X * open a directory.
X */
XDIR *
Xopendir(name)
Xchar *name;
X{
X	register DIR *dirp;
X	register int fd;
X
X	if ((fd = open(name, 0)) == -1)
X		return NULL;
X	if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
X		close (fd);
X		return NULL;
X	}
X	dirp->dd_fd = fd;
X	dirp->dd_loc = 0;
X	return dirp;
X}
X
X/*
X * read an old style directory entry and present it as a new one
X */
X#define	ODIRSIZ	14
X
Xstruct	olddirect {
X	short	od_ino;
X	char	od_name[ODIRSIZ];
X};
X
X/*
X * get next entry in a directory.
X */
Xstruct direct *
Xreaddir(dirp)
Xregister DIR *dirp;
X{
X	register struct olddirect *dp;
X	static struct direct dir;
X
X	for (;;) {
X		if (dirp->dd_loc == 0) {
X			dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, 
X			    DIRBLKSIZ);
X			if (dirp->dd_size <= 0)
X				return NULL;
X		}
X		if (dirp->dd_loc >= dirp->dd_size) {
X			dirp->dd_loc = 0;
X			continue;
X		}
X		dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
X		dirp->dd_loc += sizeof(struct olddirect);
X		if (dp->od_ino == 0)
X			continue;
X		dir.d_ino = dp->od_ino;
X		strncpy(dir.d_name, dp->od_name, ODIRSIZ);
X		dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
X		dir.d_namlen = strlen(dir.d_name);
X		dir.d_reclen = DIRSIZ(&dir);
X		return (&dir);
X	}
X}
X
X/*
X * close a directory.
X */
Xvoid
Xclosedir(dirp)
Xregister DIR *dirp;
X{
X	close(dirp->dd_fd);
X	dirp->dd_fd = -1;
X	dirp->dd_loc = 0;
X	free((char *)dirp);
X}
X
X/*
X * seek to an entry in a directory.
X * Only values returned by "telldir" should be passed to seekdir.
X */
Xvoid
Xseekdir(dirp, loc)
Xregister DIR *dirp;
Xlong loc;
X{
X	long curloc, base, offset;
X	struct direct *dp;
X	long lseek(), telldir();
X
X	curloc = telldir(dirp);
X	if (loc == curloc)
X		return;
X	base = loc & ~(DIRBLKSIZ - 1);
X	offset = loc & (DIRBLKSIZ - 1);
X	(void) lseek(dirp->dd_fd, base, 0);
X	dirp->dd_loc = 0;
X	while (dirp->dd_loc < offset) {
X		dp = readdir(dirp);
X		if (dp == NULL)
X			return;
X	}
X}
X
X/*
X * return a pointer into a directory
X */
Xlong
Xtelldir(dirp)
XDIR *dirp;
X{
X	return lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc;
X}
!END OF FILE!
: !CUT HERE!
: run this thru sh, e.g. sh file
PATH=:/bin:/usr/bin; export PATH
echo extracting ndir.h
sed 's/^X//' <<'!END OF FILE!' >ndir.h
X#ifndef DEV_BSIZE
X#define	DEV_BSIZE	512
X#endif
X#define DIRBLKSIZ	DEV_BSIZE
X#define	MAXNAMLEN	255
X
Xstruct	direct {
X	long	d_ino;			/* inode number of entry */
X	short	d_reclen;		/* length of this record */
X	short	d_namlen;		/* length of string in d_name */
X	char	d_name[MAXNAMLEN + 1];	/* name must be no longer than this */
X};
X
X/*
X * The DIRSIZ macro gives the minimum record length which will hold
X * the directory entry.  This requires the amount of space in struct direct
X * without the d_name field, plus enough space for the name with a terminating
X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
X */
X
X#ifdef DIRSIZ
X#undef DIRSIZ
X#endif /* DIRSIZ */
X#define DIRSIZ(dp) \
X    ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
X
X/*
X * Definitions for library routines operating on directories.
X */
Xtypedef struct _dirdesc {
X	int	dd_fd;
X	long	dd_loc;
X	long	dd_size;
X	char	dd_buf[DIRBLKSIZ];
X} DIR;
X#ifndef NULL
X#define NULL 0
X#endif
Xextern	DIR *opendir();
Xextern	struct direct *readdir();
Xextern	void closedir();
X
X#define rewinddir(dirp)	seekdir((dirp), (long)0)
!END OF FILE!