cyrus@pprg.unm.edu (Tait Cyrus) (11/21/88)
I am trying to get the 4.3 Tahoe dump/restore/rmt stuff to run uder SunOS 3.5. rdump seems to work fine, but rrestore does not. In dirs.c around line 108 there is the code: if (ip == NULL || (ip->di_mode & IFMT) != IFDIR) { (void) fclose(df); dirp = opendir(dirfile); if (dirp == NULL) perror("opendir"); if (mf != NULL) (void) fclose(mf); i = dirlookup("."); Two problems I see here. 1) dirfile is NOT a directory but a file (created by rrestore) 2) If dirp == NULL, then in addtion to the perror call, exit should also be called. My question then is why is the code trying to open a directory that does NOT exist. Thanks for any help/suggestions/bug fixes etc... --- @__________@ W. Tait Cyrus (505) 277-0806 /| /| University of New Mexico / | / | Dept of ECE - Parallel Processing Research Group @__|_______@ | Albuquerque, New Mexico 87131 | | | | | | hc | | e-mail: | @.......|..@ cyrus@pprg.unm.edu | / | / @/_________@/
dpz@dorm.rutgers.edu (David P. Zimmerman) (11/21/88)
In article <23669@pprg.unm.edu> cyrus@pprg.unm.edu (Tait Cyrus) writes: > I am trying to get the 4.3 Tahoe dump/restore/rmt stuff to run > uder SunOS 3.5. rdump seems to work fine, but rrestore does not. Well, that doesn't make it a bug, does it? BSD4.3 and SunOS 3.x are different beasts, right down to the opendir() library call. Here's my fixes to the 4.3BSD [r]restore to make it work under SunOS3.x (and also on Celerity 1200s and Pyramids). You can see what I've changed, and a bit of examination will explain why (RTFSC :-). David : This is a shell archive. : Remove everything above this line and : run the following text with /bin/sh to create: : README : Makefile.diff : dirs.c.diff : dumprestore.h.diff : interactive.c.diff : main.c.diff : restore.h.diff : tape.c.diff : opendir.c : telldir.c : This archive created: Sun Nov 20 19:24:15 1988 cat << 'SHAR_EOF' > README dpz's changes to the standard 4.3BSD restore for compatible Sun SunOS 3.x, Sun SunOS 4.0, Pyramid OSx4.1, and Celerity 3.4 restores: - replacing various #include files with equivalents - adding DIRBLKSIZ #define, making it largest DEV_BSIZE of all architectures - copying DIR struct definition to RST_DIR, changing char *dd_buf in it to char dd_buf[DIRBLKSIZ], changing all routines that use DIR to use RST_DIR - copying 4.3 opendir() to rst_4_3_opendir() and changing appropriate routines to call that instead of opendir() - copying 4.3 telldir() to rst_4_3_telldir(), changing appropriate routines to call that instead of telldir() - compile on Sun SunOS 4.0 with -DSUNOS4 in Makefile and link statically - generalizing "struct direct" to a typedef, since SunOS 4.0 has a field in it that doesn't exist on disk - adding/modifying /usr/include/protocols/dumprestore.h: - have TP_BSIZE equal the largest disk block size across all three architectures (2048 in this case) - adjusting NTREC and HIGHDENSITYTREC down to balance my higher TP_BSIZE - adjusting DUMPOUTFMT and DUMPINFMT to have the highest number across all three architectures for %XXs - adding CARTRIDGETREC for some reason Frills: - modifying Makefile so ${CFLAGS} is included in final .o combining - adding Gary Winiger's epoch dump date mod (his comments below) - adding Gary Winiger's interactive.c seg violation mods (cmts below) From: gww@elxsi.UUCP (Gary Winiger) When restore lists the dates the the dump encompases such as with the -t option, it will list the epoch date for the from date of a level 0 dump. From: gww@elxsi.UUCP (Gary Winiger) When running /etc/restore in interactive mode, any attempt to reference a subdirectory will cause a segmentation violation on systems that do not permit dereferencing a NULL pointer. SHAR_EOF cat << 'SHAR_EOF' > Makefile.diff *** Makefile.ORIG Sat Jan 9 16:27:02 1988 --- Makefile Sat Jan 9 16:26:58 1988 *************** *** 16,22 **** cc ${LDFLAGS} ${CFLAGS} -o restore ${OBJS} tape.o rrestore: ${OBJS} rtape.o dumprmt.o ! cc ${LDFLAGS} -o rrestore ${OBJS} rtape.o dumprmt.o rtape.o: tape.c cp tape.c rtape.c --- 16,22 ---- cc ${LDFLAGS} ${CFLAGS} -o restore ${OBJS} tape.o rrestore: ${OBJS} rtape.o dumprmt.o ! cc ${LDFLAGS} ${CFLAGS} -o rrestore ${OBJS} rtape.o dumprmt.o rtape.o: tape.c cp tape.c rtape.c SHAR_EOF cat << 'SHAR_EOF' > dirs.c.diff *** dirs.c.ORIG Sat Jan 9 16:27:02 1988 --- dirs.c Wed Aug 17 17:39:13 1988 *************** *** 43,53 **** */ static daddr_t seekpt; static FILE *df, *mf; ! static DIR *dirp; static char dirfile[32] = "#"; /* No file */ static char modefile[32] = "#"; /* No file */ extern ino_t search(); ! struct direct *rst_readdir(); extern void rst_seekdir(); /* --- 43,54 ---- */ static daddr_t seekpt; static FILE *df, *mf; ! static RST_DIR *dirp; static char dirfile[32] = "#"; /* No file */ static char modefile[32] = "#"; /* No file */ extern ino_t search(); ! RST_DIR *rst_4_3_opendir(); ! UNIXDIRECT *rst_readdir(); extern void rst_seekdir(); /* *************** *** 71,77 **** register int i; register struct dinode *ip; struct inotab *itp; ! struct direct nulldir; int putdir(), null(); vprintf(stdout, "Extract directories from tape\n"); --- 72,78 ---- register int i; register struct dinode *ip; struct inotab *itp; ! UNIXDIRECT nulldir; int putdir(), null(); vprintf(stdout, "Extract directories from tape\n"); *************** *** 105,111 **** ip = curfile.dip; if (ip == NULL || (ip->di_mode & IFMT) != IFDIR) { (void) fclose(df); ! dirp = opendir(dirfile); if (dirp == NULL) perror("opendir"); if (mf != NULL) --- 106,112 ---- ip = curfile.dip; if (ip == NULL || (ip->di_mode & IFMT) != IFDIR) { (void) fclose(df); ! dirp = rst_4_3_opendir(dirfile); if (dirp == NULL) perror("opendir"); if (mf != NULL) *************** *** 144,150 **** long (*todo)(); { register struct inotab *itp; ! register struct direct *dp; register struct entry *np; int namelen; daddr_t bpt; --- 145,151 ---- long (*todo)(); { register struct inotab *itp; ! register UNIXDIRECT *dp; register struct entry *np; int namelen; daddr_t bpt; *************** *** 182,188 **** else fprintf(stderr, "Warning: `..' missing from directory %s\n", pname); ! bpt = telldir(dirp); /* * a zero inode signals end of directory */ --- 183,189 ---- else fprintf(stderr, "Warning: `..' missing from directory %s\n", pname); ! bpt = rst_4_3_telldir(dirp); /* * a zero inode signals end of directory */ *************** *** 197,203 **** rst_seekdir(dirp, bpt, itp->t_seekpt); } dp = rst_readdir(dirp); ! bpt = telldir(dirp); } if (dp == NULL) fprintf(stderr, "corrupted directory: %s.\n", locname); --- 198,204 ---- rst_seekdir(dirp, bpt, itp->t_seekpt); } dp = rst_readdir(dirp); ! bpt = rst_4_3_telldir(dirp); } if (dp == NULL) fprintf(stderr, "corrupted directory: %s.\n", locname); *************** *** 246,252 **** ino_t inum; char *cp; { ! register struct direct *dp; register struct inotab *itp; int len; --- 247,253 ---- ino_t inum; char *cp; { ! register UNIXDIRECT *dp; register struct inotab *itp; int len; *************** *** 270,279 **** char *buf; int size; { ! struct direct cvtbuf; register struct odirect *odp; struct odirect *eodp; ! register struct direct *dp; long loc, i; extern int Bcvt; --- 271,280 ---- char *buf; int size; { ! UNIXDIRECT cvtbuf; register struct odirect *odp; struct odirect *eodp; ! register UNIXDIRECT *dp; long loc, i; extern int Bcvt; *************** *** 286,292 **** } } else { for (loc = 0; loc < size; ) { ! dp = (struct direct *)(buf + loc); if (Bcvt) { swabst("l2s", (char *) dp); } --- 287,293 ---- } } else { for (loc = 0; loc < size; ) { ! dp = (UNIXDIRECT *)(buf + loc); if (Bcvt) { swabst("l2s", (char *) dp); } *************** *** 314,324 **** * add a new directory entry to a file. */ putent(dp) ! struct direct *dp; { dp->d_reclen = DIRSIZ(dp); if (dirloc + dp->d_reclen > DIRBLKSIZ) { ! ((struct direct *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev; (void) fwrite(dirbuf, 1, DIRBLKSIZ, df); dirloc = 0; --- 315,325 ---- * add a new directory entry to a file. */ putent(dp) ! UNIXDIRECT *dp; { dp->d_reclen = DIRSIZ(dp); if (dirloc + dp->d_reclen > DIRBLKSIZ) { ! ((UNIXDIRECT *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev; (void) fwrite(dirbuf, 1, DIRBLKSIZ, df); dirloc = 0; *************** *** 334,340 **** flushent() { ! ((struct direct *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev; (void) fwrite(dirbuf, (int)dirloc, 1, df); seekpt = ftell(df); dirloc = 0; --- 335,341 ---- flushent() { ! ((UNIXDIRECT *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev; (void) fwrite(dirbuf, (int)dirloc, 1, df); seekpt = ftell(df); dirloc = 0; *************** *** 342,348 **** dcvt(odp, ndp) register struct odirect *odp; ! register struct direct *ndp; { bzero((char *)ndp, (long)(sizeof *ndp)); --- 343,349 ---- dcvt(odp, ndp) register struct odirect *odp; ! register UNIXDIRECT *ndp; { bzero((char *)ndp, (long)(sizeof *ndp)); *************** *** 354,360 **** /* * Seek to an entry in a directory. ! * Only values returned by ``telldir'' should be passed to rst_seekdir. * This routine handles many directories in a single file. * It takes the base of the directory in the file, plus * the desired seek offset into it. --- 355,361 ---- /* * Seek to an entry in a directory. ! * Only values returned by ``rst_4_3_telldir'' should be passed to rst_seekdir. * This routine handles many directories in a single file. * It takes the base of the directory in the file, plus * the desired seek offset into it. *************** *** 361,371 **** */ void rst_seekdir(dirp, loc, base) ! register DIR *dirp; daddr_t loc, base; { ! if (loc == telldir(dirp)) return; loc -= base; if (loc < 0) --- 362,372 ---- */ void rst_seekdir(dirp, loc, base) ! register RST_DIR *dirp; daddr_t loc, base; { ! if (loc == rst_4_3_telldir(dirp)) return; loc -= base; if (loc < 0) *************** *** 379,389 **** /* * get next entry in a directory. */ ! struct direct * rst_readdir(dirp) ! register DIR *dirp; { ! register struct direct *dp; for (;;) { if (dirp->dd_loc == 0) { --- 380,390 ---- /* * get next entry in a directory. */ ! UNIXDIRECT * rst_readdir(dirp) ! register RST_DIR *dirp; { ! register UNIXDIRECT *dp; for (;;) { if (dirp->dd_loc == 0) { *************** *** 398,404 **** dirp->dd_loc = 0; continue; } ! dp = (struct direct *)(dirp->dd_buf + dirp->dd_loc); if (dp->d_reclen == 0 || dp->d_reclen > DIRBLKSIZ + 1 - dirp->dd_loc) { dprintf(stderr, "corrupted directory: bad reclen %d\n", --- 399,405 ---- dirp->dd_loc = 0; continue; } ! dp = (UNIXDIRECT *)(dirp->dd_buf + dirp->dd_loc); if (dp->d_reclen == 0 || dp->d_reclen > DIRBLKSIZ + 1 - dirp->dd_loc) { dprintf(stderr, "corrupted directory: bad reclen %d\n", *************** *** 417,426 **** } } /* * Simulate the opening of a directory */ ! DIR * rst_opendir(name) char *name; { --- 418,431 ---- } } + #include "opendir.c" + + #include "telldir.c" + /* * Simulate the opening of a directory */ ! RST_DIR * rst_opendir(name) char *name; { SHAR_EOF cat << 'SHAR_EOF' > dumprestore.h.diff *** dumprestore.h.ORIG Mon Apr 18 21:33:00 1988 --- dumprestore.h Tue Aug 16 17:08:45 1988 *************** *** 13,26 **** * NTREC is the number of TP_BSIZE blocks that are written * in each tape record. HIGHDENSITYTREC is the number of * TP_BSIZE blocks that are written in each tape record on ! * 6250 BPI or higher density tapes. * * TP_NINDIR is the number of indirect pointers in a TS_INODE * or TS_ADDR record. Note that it must be a power of two. */ ! #define TP_BSIZE 1024 ! #define NTREC 10 ! #define HIGHDENSITYTREC 32 #define TP_NINDIR (TP_BSIZE/2) #define TS_TAPE 1 --- 13,29 ---- * NTREC is the number of TP_BSIZE blocks that are written * in each tape record. HIGHDENSITYTREC is the number of * TP_BSIZE blocks that are written in each tape record on ! * 6250 BPI or higher density tapes. CARTRIDGETREC is the ! * number of TP_BSIZE blocks that are written in each tape ! * record on cartridge tapes. * * TP_NINDIR is the number of indirect pointers in a TS_INODE * or TS_ADDR record. Note that it must be a power of two. */ ! #define TP_BSIZE 2048 ! #define NTREC 5 ! #define HIGHDENSITYTREC 16 ! #define CARTRIDGETREC 31 #define TP_NINDIR (TP_BSIZE/2) #define TS_TAPE 1 *************** *** 52,57 **** #define spcl u_spcl.s_spcl ! #define DUMPOUTFMT "%-16s %c %s" /* for printf */ /* name, incno, ctime(date) */ ! #define DUMPINFMT "%16s %c %[^\n]\n" /* inverse for scanf */ --- 55,60 ---- #define spcl u_spcl.s_spcl ! #define DUMPOUTFMT "%-22s %c %s" /* for printf */ /* name, incno, ctime(date) */ ! #define DUMPINFMT "%22s %c %[^\n]\n" /* inverse for scanf */ SHAR_EOF cat << 'SHAR_EOF' > interactive.c.diff *** interactive.c.ORIG Sat Jan 9 16:27:01 1988 --- interactive.c Tue Jul 12 17:00:11 1988 *************** *** 398,409 **** register struct arglist *ap; { static struct afile single; int size; ap->head = ap->last = (struct afile *)0; size = expand(arg, 0, ap); if (size == 0) { ! single.fnum = lookupname(arg)->e_ino; single.fname = savename(arg); ap->head = &single; ap->last = ap->head + 1; --- 398,411 ---- register struct arglist *ap; { static struct afile single; + struct entry *ep; int size; ap->head = ap->last = (struct afile *)0; size = expand(arg, 0, ap); if (size == 0) { ! ep = lookupname(arg); ! single.fnum = ep != NIL ? ep->e_ino : 0; single.fname = savename(arg); ap->head = &single; ap->last = ap->head + 1; *************** *** 423,432 **** int count, size; char dir = 0; char *rescan = 0; ! DIR *dirp; register char *s, *cs; int sindex, rindex, lindex; ! struct direct *dp; register char slash; register char *rs; register char c; --- 425,434 ---- int count, size; char dir = 0; char *rescan = 0; ! RST_DIR *dirp; register char *s, *cs; int sindex, rindex, lindex; ! UNIXDIRECT *dp; register char slash; register char *rs; register char c; *************** *** 571,577 **** * Construct a matched name. */ addg(dp, as1, as3, ap) ! struct direct *dp; char *as1, *as3; struct arglist *ap; { --- 573,579 ---- * Construct a matched name. */ addg(dp, as1, as3, ap) ! UNIXDIRECT *dp; char *as1, *as3; struct arglist *ap; { *************** *** 609,618 **** char *basename; { register struct afile *fp; ! register struct direct *dp; static struct arglist alist = { 0, 0, 0, 0, "ls" }; struct afile single; ! DIR *dirp; if ((dirp = rst_opendir(name)) == NULL) { single.fnum = ino; --- 611,620 ---- char *basename; { register struct afile *fp; ! register UNIXDIRECT *dp; static struct arglist alist = { 0, 0, 0, 0, "ls" }; struct afile single; ! RST_DIR *dirp; if ((dirp = rst_opendir(name)) == NULL) { single.fnum = ino; SHAR_EOF cat << 'SHAR_EOF' > main.c.diff *** main.c.ORIG Sat Jan 9 16:27:00 1988 --- main.c Tue Jul 12 16:39:19 1988 *************** *** 58,64 **** --- 58,66 ---- char *inputdev = "/dev/rmt8"; char *symtbl = "./restoresymtable"; char name[MAXPATHLEN]; + #ifndef SUNOS4 int (*signal())(); + #endif extern int onintr(); if (signal(SIGINT, onintr) == SIG_IGN) SHAR_EOF cat << 'SHAR_EOF' > restore.h.diff *** restore.h.ORIG Sat Jan 9 16:27:01 1988 --- restore.h Tue Jul 12 17:02:25 1988 *************** *** 8,17 **** #include <stdio.h> #include <sys/param.h> ! #include <sys/inode.h> ! #include <sys/fs.h> #include <sys/dir.h> /* * Flags */ --- 8,42 ---- #include <stdio.h> #include <sys/param.h> ! #include <sys/time.h> ! #include <sys/vnode.h> ! #include <ufs/inode.h> ! #include <ufs/fs.h> #include <sys/dir.h> + #ifdef SUNOS4 + typedef struct { + u_long d_fileno; /* file number of entry */ + u_short d_reclen; /* length of this record */ + u_short d_namlen; /* length of string in d_name */ + char d_name[MAXNAMLEN + 1]; /* name (up to MAXNAMLEN + 1) */ + } UNIXDIRECT; + #else + typedef struct direct UNIXDIRECT; + #endif + + #define DIRBLKSIZ 2048 + + typedef struct _rstdirdesc { + int dd_fd; + long dd_loc; + long dd_size; + long dd_bbase; + long dd_entno; + long dd_bsize; + char dd_buf[DIRBLKSIZ]; + } RST_DIR; + /* * Flags */ *************** *** 76,83 **** extern char *flagvalues(); extern ino_t lowerbnd(); extern ino_t upperbnd(); ! extern DIR *rst_opendir(); ! extern struct direct *rst_readdir(); #define NIL ((struct entry *)(0)) /* * Constants associated with entry structs --- 101,108 ---- extern char *flagvalues(); extern ino_t lowerbnd(); extern ino_t upperbnd(); ! extern RST_DIR *rst_opendir(); ! extern UNIXDIRECT *rst_readdir(); #define NIL ((struct entry *)(0)) /* * Constants associated with entry structs SHAR_EOF cat << 'SHAR_EOF' > tape.c.diff *** tape.c.ORIG Sat Jan 9 16:27:03 1988 --- tape.c Sun May 29 19:09:30 1988 *************** *** 153,159 **** } if (vflag || command == 't') { fprintf(stdout, "Dump date: %s", ctime(&spcl.c_date)); ! fprintf(stdout, "Dumped from: %s", ctime(&spcl.c_ddate)); } dumptime = spcl.c_ddate; dumpdate = spcl.c_date; --- 153,161 ---- } if (vflag || command == 't') { fprintf(stdout, "Dump date: %s", ctime(&spcl.c_date)); ! fprintf(stdout, "Dumped from: %s", ! (spcl.c_ddate == (time_t)0) ! ? "the epoch\n" : ctime(&spcl.c_ddate)); } dumptime = spcl.c_ddate; dumpdate = spcl.c_date; SHAR_EOF cat << 'SHAR_EOF' > opendir.c /* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* * open a directory. */ RST_DIR * rst_4_3_opendir(name) char *name; { register RST_DIR *dirp; register int fd; if ((fd = open(name, 0)) == -1) return NULL; if ((dirp = (RST_DIR *)malloc(sizeof(RST_DIR))) == NULL) { close (fd); return NULL; } dirp->dd_fd = fd; dirp->dd_loc = 0; return dirp; } SHAR_EOF cat << 'SHAR_EOF' > telldir.c /* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ /* * return a pointer into a directory */ long rst_4_3_telldir(dirp) RST_DIR *dirp; { extern long lseek(); return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc); } SHAR_EOF : End of shell archive exit 0 -- David P. Zimmerman, the Dorm Networking Pilot Project, the UUCP Project, etc dpz@dorm.rutgers.edu rutgers!dpz dpzimmerman@zodiac.bitnet
vixie@decwrl.dec.com (Paul Vixie) (11/21/88)
# 1) dirfile is NOT a directory but a file (created by rrestore) I don't know about the rest of your article, but this I can answer: it knows it's trying to open a dirfile, it just copied it in from the tape. The ndir(3) routines don't care if it's really a directory, just as long as the format is compatible. The routines are read-only since they run in user-mode; if you point 'em at a file that happens to look like a directory, they work fine. (on my 4.3bsd machine:) === vixie@beast-> /bin/cp . foo cp: .: Is a directory (copying as plain file). vixie@beast-> /bin/ls -f foo . .rhosts .profile .mh_profile .uwmrc foo .. ueg .joverc .signature ftpd Etc .cshrc .mailrc .Xres routed === -- Paul Vixie Work: vixie@decwrl.dec.com decwrl!vixie +1 415 853 6600 Play: paul@vixie.sf.ca.us vixie!paul +1 415 864 7013
guy@auspex.UUCP (Guy Harris) (11/23/88)
># 1) dirfile is NOT a directory but a file (created by rrestore) > >I don't know about the rest of your article, but this I can answer: it knows >it's trying to open a dirfile, it just copied it in from the tape. The ndir(3) >routines don't care if it's really a directory, just as long as the format is >compatible. The routines are read-only since they run in user-mode; if you >point 'em at a file that happens to look like a directory, they work fine. Note that under SunOS: 1) The directory library routines use "getdirentries()" in 2.x and 3.x releases, and "getdents()" in 4.0. 2) Those routines transform the contents of the file; they are not equivalent to "read()" on a directory file. 3) I don't know whether those routines work on non-directory files. 4) In any case, "opendir()" returns an error when you try to open a file that isn't a directory. The bottom line is that the format isn't compatible, so you can't point the directory library routines at a non-directory, even if it happens to look like one. The SunOS version of "restore" contains what amounts to a copy of the "old" directory library (the one that directly reads the directory file).
vixie@decwrl.dec.com (Paul Vixie) (11/24/88)
In article <486@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes:
# [...]
# Note that under SunOS:
#
# 1) The directory library routines use "getdirentries()" in 2.x
# and 3.x releases, and "getdents()" in 4.0.
# [...]
# The SunOS version of "restore" contains what amounts to a copy of the
# "old" directory library (the one that directly reads the directory file).
Thanks, Guy. It looks like you're *still* the best Usenet info source about
SunOS even though you don't post from Sun anymore.
One question, if you (or anyone else) knows: why was this change made? I
know Sun would never, ever make a gratuitous, incompatible change to the
semantics of a library routine. What was the motive (this time)?
--
Paul Vixie
Work: vixie@decwrl.dec.com decwrl!vixie +1 415 853 6600
Play: paul@vixie.sf.ca.us vixie!paul +1 415 864 7013
guy@auspex.UUCP (Guy Harris) (11/26/88)
>One question, if you (or anyone else) knows: why was this change made?
Which change? The change to use "getdirentries()" or the change to use
"getdents()"?
The former change was made so that directory reads could be
distinguished from plain reads of a directory file. Directory reads
should return information in some standard format, regardless of how the
actual directory file is represented.
An alternative would have been to make the "read" system call, when
executed on a directory, act like "getdirentries()" or "getdents()";
this would actually have broken more existing binaries than adding
"getdirentries()" (at least with a new system call, old binaries could
continue to read UFS directories, although they might fall apart on
directories read over NFS, or directories read from a V7/S5 file system,
or...). You have to return a "directory cookie" with each directory
entry, so that the system can give you the "directory cookie" when you
do a "telldir"; you can't assume that the underlying directory works
like a UFS directory (i.e., that you can calculate how much some
internal seek pointer has moved, based purely on the data you got back
from the "read").
The latter change was made because "getdents()" has a better interface
than "getdirentries()"; instead of returning one directory "cookie" that
gives an "address" within the directory, it returns one for each entry,
so that the software doesn't have to assume it "knows" how directory
cookies work. The NFS "readdir" operation resembles "getdents()" more
than it resembles "getdirentries()" (for that reason).
gwyn@smoke.BRL.MIL (Doug Gwyn ) (11/26/88)
In article <936@bacchus.dec.com> vixie@decwrl.dec.com (Paul Vixie) writes: >In article <486@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes: ># 1) The directory library routines use "getdirentries()" in 2.x ># and 3.x releases, and "getdents()" in 4.0. >One question, if you (or anyone else) knows: why was this change made? I >know Sun would never, ever make a gratuitous, incompatible change to the >semantics of a library routine. What was the motive (this time)? getdirentries() and getdents() are two system call interfaces that perform essentially the same function. One was invented by one organization and the other by another company. getdents() is the UNIX SVR3 flavor. My public-domain implementation of the directory routines isolates all the UNIX system vagaries in a (possibly emulated) getdents() function; when getdirentries() is available, the getdents() emulation uses it. On systems without sufficient kernel support, the getdents() emulation reads the directory file directly (two flavors of that: one for the original UNIX file system and one for the 4.2BSD long-entry-name file system). The direct-reading scheme would not work right for so-called "transparent" network file systems unless the network file system maps the directory entries to the local format. Most don't do this but some do.
ed@mtxinu.UUCP (Ed Gould) (11/27/88)
># 1) The directory library routines use "getdirentries()" in 2.x ># and 3.x releases, and "getdents()" in 4.0. >One question, if you (or anyone else) knows: why was this change made? I >know Sun would never, ever make a gratuitous, incompatible change to the >semantics of a library routine. What was the motive (this time)? The change was made for NFS, since the format of a directory on a remote system can not be assumed to be the same as the local system. Thus, the NFS protocol passes directory information around in a standard format, and it is up to the local system to interpret it in a sensible way. The library *interface* is unchanged, and its behaviour when pointed to a directory is likewise unchanged. Only when the new library routines are pointed to a non-directory is anything different. I don't believe the 4.2 directory routines' behaviour were defined for non-directories. -- Ed Gould mt Xinu, 2560 Ninth St., Berkeley, CA 94710 USA {ucbvax,uunet}!mtxinu!ed +1 415 644 0146 "I'll fight them as a woman, not a lady. I'll fight them as an engineer."