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!