/* * Copyright (c) 1991-1994 by the University of Southern California * * For copying and distribution information, please see the file * . */ #include #include #define DIRSIZ_MACRO /* needed for HPUX; does no harm otherwise. */ #include #include /* For malloc or free */ #include /* Needed if not already included. */ #ifdef USE_SYS_DIR_H /* Support for SYS_DIR_H may be finally dead. I hope. */ #include #else #include #endif #include #include #include /* Maximum open virtual directories */ #define MAX_VDDESC 16 static struct dirent *dirbuf[MAX_VDDESC + 1] = {NULL}; static int dirpos[MAX_VDDESC + 1] = {0}; static int dirbsz[MAX_VDDESC + 1] = {0}; int p__getvdirentries(int fd, char *buf, int nbytes, int *basep) { int bytes = 0; struct dirent *dp; char *bp; if(fd > -1) return(0); if(fd < - MAX_VDDESC) return(0); dp = (struct dirent *) ((char *)dirbuf[-fd] + dirpos[-fd]); while(dp->d_reclen && (dp->d_reclen <= nbytes)) { bcopy(dp,buf,dp->d_reclen); nbytes = nbytes - (unsigned short) dp->d_reclen; buf = buf + (unsigned short) dp->d_reclen; bytes = bytes + (unsigned short) dp->d_reclen; bp = (char *) dp;bp += dp->d_reclen;dp = (struct dirent *) bp; } *basep = dirpos[-fd]; dirpos[-fd] = dirpos[-fd] + bytes; return(bytes); } int p__readvdirentries(char *dirname) { VDIR_ST dir_st; VDIR dir= &dir_st; VLINK l; long dsize = 0; int dirnum = 0; struct dirent *dp; int tmp; vdir_init(dir); check_pfs_default(); /* If disabled, do no mapping */ if(pfs_enable == PMAP_DISABLE) return(PSUCCESS); /* This is a kludge. We should not be modifying the */ /* path arg, but... */ if(pfs_enable == PMAP_ATSIGN) { if(*dirname == '@') { strcpy(dirname,dirname+1); return(PSUCCESS); } } if(pfs_enable == PMAP_COLON) { if(*dirname == ':') dirname++; else return(PSUCCESS); } p__compat_initialize(); tmp = rd_vdir(dirname,0,dir,RVD_LREMEXP); if(tmp) return(tmp); l = dir->links; while(l) { /* The next statement should track the DIRSIZ macro */ dsize = dsize + (sizeof(struct dirent) - (MAXNAMLEN+1)) + ((strlen(l->name)+1 +3) & ~3); l = l->next; } /* This is just in case */ dsize = dsize + 256; dirnum = 0; while(dirnum++ <= MAX_VDDESC) { if(!dirbuf[dirnum]) break; } if(dirnum > MAX_VDDESC) RETURNPFAILURE; dp = (struct dirent *) malloc(dsize); dirbuf[dirnum] = dp; dirpos[dirnum] = 0; dirbsz[dirnum] = dsize; l = dir->links; while(l) { dp->d_ino = (unsigned long) 999; #if !defined (SOLARIS) dp->d_namlen = (unsigned short) strlen(l->name); #endif dp->d_reclen = (unsigned short) DIRSIZ(dp); strcpy(dp->d_name,l->name); dp = (struct dirent *) ((char *) dp + dp->d_reclen); l = l->next; } dp->d_ino = (unsigned long) 0; dp->d_reclen = (unsigned short) 0; #if !defined (SOLARIS) dp->d_namlen = (unsigned short) 0; #endif *(dp->d_name) = '\0'; vllfree(dir->links); vllfree(dir->ulinks); return(-dirnum); } int p__delvdirentries(int desc) { if(desc > -1) RETURNPFAILURE; if(desc < - MAX_VDDESC) RETURNPFAILURE; if(dirbuf[- desc]) { free(dirbuf[- desc]); dirbuf[- desc] = NULL; return(PSUCCESS); } RETURNPFAILURE; } int p__seekvdir(int desc, int pos) { if(desc > -1) RETURNPFAILURE; if(desc < - MAX_VDDESC) RETURNPFAILURE; if(!dirbuf[- desc]) RETURNPFAILURE; dirpos[-desc] = pos; return(PSUCCESS); } int p__getvdbsize(int desc, int pos) { if(desc > -1) RETURNPFAILURE; if(desc < - MAX_VDDESC) RETURNPFAILURE; if(!dirbuf[- desc]) RETURNPFAILURE; return(dirbsz[-desc]); }