--- researchv9/cmd/sh/expand.c 2018/04/24 17:21:59 1.1 +++ researchv9/cmd/sh/expand.c 2018/04/24 17:25:03 1.1.1.2 @@ -324,8 +324,11 @@ DIR * opendir(name) register char *name; { + int i; DIR dirbuf, *dirp; - struct stat statb; + register char *p; + struct stat st; + char buf[MAXNAMELEN+1]; register char *s; @@ -334,13 +337,61 @@ register char *name; *s &= STRIP; if ((dirbuf.dd_fd = open(buf, 0)) < 0) return(NULL); - if (fstat(dirbuf.dd_fd, &statb)!=0 || (statb.st_mode & S_IFMT)!=S_IFDIR){ + if (fstat(dirbuf.dd_fd, &st)!=0 || (st.st_mode & S_IFMT)!=S_IFDIR){ close(dirbuf.dd_fd); return(NULL); } - dirbuf.dd_loc = 0; dirp = (DIR *)shalloc(sizeof(DIR)); *dirp = dirbuf; + dirp->dd_loc = 0; + i = read(dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ); + if(i <= 0) { + close(dirp->dd_fd); + free(dirp); + return(0); + } + lseek(dirp->dd_fd, 0L, 0); +/* the cray and the 68000 are big-endians, vax is not + v9: ??.0000000000000??..000000000000||||||||| + cray: ????????.00000000000000000000000????????..0000000000000000000000||||||| + 68k: ????0X01.000????0X02..00|||||||| X=12 + vaxn: ????X010.000????X020..00||||||| + /* shortest cray sys v dir is 64 bytes, shortest v8 is 32, and shortest + * sun 4.2(68k) is 24 (except it's supposed to be a whole block long) + */ + if(i < 24) /* mysteriously short directory */ + goto old; + p = dirp->dd_buf; + if(p[8] != '.') { +old: + if (fstat(dirp->dd_fd, &st) < 0) { + close(dirp->dd_fd); + free(dirp); + return(0); + } + if (st.st_ino == *(ino_t *)dirp->dd_buf) + dirp->dd_type = TOLD; + else + dirp->dd_type = TOLDSWAP; + return(dirp); + } + if(p[20] == '.' && p[21] == '.') { /* bsd-like or bogus */ + if(*(short *)&p[4] == 0x000c) { + dirp->dd_type = TBSD; + return(dirp); + } + if(*(short *)&p[4] == 0x0c00) { + dirp->dd_type = TBSDSWAP; + return(dirp); + } + dirp->dd_type = TUNK; + return(dirp); + } + if(i >= 32 && p[9] == 0 && p[40] == '.' && p[41] == '.' && p[42] == 0) { + dirp->dd_type = TCRAY; + return(dirp); + } + dirp->dd_type = TUNK; return(dirp); }