예제 #1
0
파일: fssh.cpp 프로젝트: mariuz/haiku
static fssh_status_t
command_ls(int argc, const char* const* argv)
{
	const char* const currentDirFiles[] = { ".", NULL };
	const char* const* files;
	if (argc >= 2)
		files = argv + 1;
	else
		files = currentDirFiles;

	for (; *files; files++) {
		const char* file = *files;
		// stat file
		struct fssh_stat st;
		fssh_status_t error = _kern_read_stat(-1, file, false, &st, sizeof(st));
		if (error != FSSH_B_OK) {
			fprintf(stderr, "Error: Failed to stat() \"%s\": %s\n", file,
				fssh_strerror(error));
			continue;
		}

		// if it is a directory, print its entries
		if (FSSH_S_ISDIR(st.fssh_st_mode)) {
			printf("%s:\n", file);

			// open dir
			int fd = _kern_open_dir(-1, file);
			if (fd < 0) {
				fprintf(stderr, "Error: Failed to open dir \"%s\": %s\n",
					file, fssh_strerror(fd));
				continue;
			}

			// iterate through the entries
			char buffer[sizeof(fssh_dirent) + FSSH_B_FILE_NAME_LENGTH];
			fssh_dirent* entry = (fssh_dirent*)buffer;
			fssh_ssize_t entriesRead = 0;
			while ((entriesRead = _kern_read_dir(fd, entry, sizeof(buffer), 1))
					== 1) {
				list_entry(file, entry->d_name);
			}

			if (entriesRead < 0) {
				fprintf(stderr, "Error: reading dir \"%s\" failed: %s\n",
					file, fssh_strerror(entriesRead));
			}

			// close dir
			error = _kern_close(fd);
			if (error != FSSH_B_OK) {
				fprintf(stderr, "Error: Closing dir \"%s\" (fd: %d) failed: "
					"%s\n", file, fd, fssh_strerror(error));
				continue;
			}
		} else
			list_entry(file);
	}

	return FSSH_B_OK;
}
예제 #2
0
파일: fuse.cpp 프로젝트: looncraz/haiku
static int
fuse_readdir(const char* path, void* buf, fuse_fill_dir_t filler,
	off_t offset, struct fuse_file_info* fi)
{
	PRINTD("##readdir\n");
	int dfp = _kern_open_dir(-1, path);
	if (dfp < FSSH_B_OK)
		return _ERR(dfp);

	fssh_ssize_t entriesRead = 0;
	struct fssh_stat f_st;
	struct stat st;
	char buffer[sizeof(fssh_dirent) + FSSH_B_FILE_NAME_LENGTH];
	fssh_dirent* dirEntry = (fssh_dirent*)buffer;
	while ((entriesRead = _kern_read_dir(dfp, dirEntry,
			sizeof(buffer), 1)) == 1) {
		fssh_memset(&st, 0, sizeof(st));
		fssh_memset(&f_st, 0, sizeof(f_st));
		fssh_status_t status = _kern_read_stat(dfp, dirEntry->d_name,
			false, &f_st, sizeof(f_st));
		if (status >= FSSH_B_OK) {
			fromFsshStatToStat(&f_st, &st);
			if (filler(buf, dirEntry->d_name, &st, 0))
				break;
		}
	}
	_kern_close(dfp);
	//TODO: check _kern_close
	return 0;
}
예제 #3
0
파일: Directory.cpp 프로젝트: mariuz/haiku
/*!	\brief Returns the BDirectory's next entries as dirent structures.
	Unlike GetNextEntry() and GetNextRef(), this method returns also
	the entries "." and "..".
	\param buf a pointer to a buffer to be filled with dirent structures of
		   the found entries
	\param count the maximal number of entries to be returned.
	\note The iterator used by this method is the same one used by
		  GetNextEntry(), GetNextRef(), Rewind() and CountEntries().
	\return
	- The number of dirent structures stored in the buffer, 0 when there are
	  no more entries to be returned.
	- \c B_BAD_VALUE: \c NULL \a buf.
	- \c B_PERMISSION_DENIED: Directory permissions didn't allow operation.
	- \c B_NO_MEMORY: Insufficient memory for operation.
	- \c B_NAME_TOO_LONG: The entry's name is too long for the buffer.
	- \c B_LINK_LIMIT: Indicates a cyclic loop within the file system.
	- \c B_BUSY: A node was busy.
	- \c B_FILE_ERROR: A general file error.
	- \c B_NO_MORE_FDS: The application has run out of file descriptors.
*/
int32
BDirectory::GetNextDirents(dirent* buf, size_t bufSize, int32 count)
{
	if (!buf)
		return B_BAD_VALUE;
	if (InitCheck() != B_OK)
		return B_FILE_ERROR;
	return _kern_read_dir(fDirFd, buf, bufSize, count);
}
예제 #4
0
파일: fssh.cpp 프로젝트: mariuz/haiku
static fssh_status_t
command_query(int argc, const char* const* argv)
{
	if (argc != 2) {
		fprintf(stderr, "Usage: %s <query string>\n", argv[0]);
		return FSSH_B_BAD_VALUE;
	}

	const char* query = argv[1];

	// get the volume ID
	fssh_dev_t volumeID = get_volume_id();
	if (volumeID < 0)
		return volumeID;

	// open query
	int fd = _kern_open_query(volumeID, query, strlen(query), 0, -1, -1);
	if (fd < 0) {
		fprintf(stderr, "Error: Failed to open query: %s\n", fssh_strerror(fd));
		return fd;
	}

	// iterate through the entries
	fssh_status_t error = FSSH_B_OK;
	char buffer[sizeof(fssh_dirent) + FSSH_B_FILE_NAME_LENGTH];
	fssh_dirent* entry = (fssh_dirent*)buffer;
	fssh_ssize_t entriesRead = 0;
	while ((entriesRead = _kern_read_dir(fd, entry, sizeof(buffer), 1)) == 1) {
		char path[FSSH_B_PATH_NAME_LENGTH];
		error = _kern_entry_ref_to_path(volumeID, entry->d_pino, entry->d_name,
			path, sizeof(path));
		if (error == FSSH_B_OK) {
			printf("  %s\n", path);
		} else {
			fprintf(stderr, "  failed to resolve entry (%8" FSSH_B_PRIdINO
				", \"%s\")\n", entry->d_pino, entry->d_name);
		}
	}

	if (entriesRead < 0) {
		fprintf(stderr, "Error: reading query failed: %s\n",
			fssh_strerror(entriesRead));
	}

	// close query
	error = _kern_close(fd);
	if (error != FSSH_B_OK) {
		fprintf(stderr, "Error: Closing query (fd: %d) failed: %s\n",
			fd, fssh_strerror(error));
	}

	return error;
}
예제 #5
0
int
readdir_r(DIR* dir, struct dirent* entry, struct dirent** _result)
{
	ssize_t count = _kern_read_dir(dir->fd, entry, sizeof(struct dirent)
		+ B_FILE_NAME_LENGTH, 1);
	if (count < B_OK)
		return count;

	if (count == 0) {
		// end of directory
		*_result = NULL;
	} else
		*_result = entry;

	return 0;
}
예제 #6
0
파일: Node.cpp 프로젝트: mmanley/Antares
/*!	\brief Returns the next attribute in the node's list of attributes.
	Every BNode maintains a pointer to its list of attributes.
	GetNextAttrName() retrieves the name of the attribute that the pointer is
	currently pointing to, and then bumps the pointer to the next attribute.
	The name is copied into the buffer, which should be at least
	B_ATTR_NAME_LENGTH characters long. The copied name is NULL-terminated.
	When you've asked for every name in the list, GetNextAttrName()
	returns \c B_ENTRY_NOT_FOUND.
	\param buffer the buffer the name of the next attribute shall be stored in
		   (must be at least \c B_ATTR_NAME_LENGTH bytes long)
	\return
	- \c B_OK: Everything went fine.
	- \c B_BAD_VALUE: \c NULL \a buffer.
	- \c B_FILE_ERROR: The object is not initialized.
	- \c B_ENTRY_NOT_FOUND: There are no more attributes, the last attribute
	  name has already been returned.
 */
status_t
BNode::GetNextAttrName(char *buffer)
{
	// We're allowed to assume buffer is at least
	// B_ATTR_NAME_LENGTH chars long, but NULLs
	// are not acceptable.
	if (buffer == NULL)
		return B_BAD_VALUE;	// /new R5 crashed when passed NULL
	if (InitAttrDir() != B_OK)
		return B_FILE_ERROR;
		
	BPrivate::Storage::LongDirEntry entry;
	ssize_t result = _kern_read_dir(fAttrFd, &entry, sizeof(entry), 1);
	if (result < 0)
		return result;
	if (result == 0)
		return B_ENTRY_NOT_FOUND;
	strlcpy(buffer, entry.d_name, B_ATTR_NAME_LENGTH);
	return B_OK;
}
예제 #7
0
struct dirent*
readdir(DIR* dir)
{
	ssize_t count;

	if (dir->seek_position != dir->current_position) {
		if (do_seek_dir(dir) != 0)
			return NULL;
	}

	if (dir->entries_left > 0) {
		struct dirent *dirent
			= (struct dirent *)((uint8 *)&dir->first_entry + dir->next_entry);

		dir->entries_left--;
		dir->next_entry += dirent->d_reclen;
		dir->seek_position++;
		dir->current_position++;

		return dirent;
	}

	// we need to retrieve new entries

	count = _kern_read_dir(dir->fd, &dir->first_entry,
		(char*)dir + DIR_BUFFER_SIZE - (char*)&dir->first_entry, USHRT_MAX);
	if (count <= 0) {
		if (count < 0)
			__set_errno(count);

		// end of directory
		return NULL;
	}

	dir->entries_left = count - 1;
	dir->next_entry = dir->first_entry.d_reclen;
	dir->seek_position++;
	dir->current_position++;

	return &dir->first_entry;
}
예제 #8
0
파일: fssh.cpp 프로젝트: mariuz/haiku
static fssh_status_t
remove_dir_contents(int parentDir, const char *name, bool force)
{
	// open the dir
	int dir = _kern_open_dir(parentDir, name);
	if (dir < 0) {
		fprintf(stderr, "Error: Failed to open dir \"%s\": %s\n", name,
			fssh_strerror(dir));
		return dir;
	}

	fssh_status_t error = FSSH_B_OK;

	// iterate through the entries
	fssh_ssize_t numRead;
	char buffer[sizeof(fssh_dirent) + FSSH_B_FILE_NAME_LENGTH];
	fssh_dirent *entry = (fssh_dirent*)buffer;
	while ((numRead = _kern_read_dir(dir, entry, sizeof(buffer), 1)) > 0) {
		// skip "." and ".."
		if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
			continue;

		error = remove_entry(dir, entry->d_name, true, force);
		if (error != FSSH_B_OK)
			break;
	}

	if (numRead < 0) {
		fprintf(stderr, "Error: Failed to read directory \"%s\": %s\n", name,
			fssh_strerror(numRead));
		error = numRead;
	}

	// close
	_kern_close(dir);

	return error;
}
예제 #9
0
static int
do_seek_dir(DIR* dir)
{
	if (dir->seek_position == dir->current_position)
		return 0;

	// If the seek position lies before the current position (the usual case),
	// rewind to the beginning.
	if (dir->seek_position < dir->current_position) {
		status_t status = _kern_rewind_dir(dir->fd);
		if (status < 0) {
			__set_errno(status);
			return -1;
		}

		dir->current_position = 0;
		dir->entries_left = 0;
	}

	// Now skip entries until we have reached seek_position.
	while (dir->seek_position > dir->current_position) {
		ssize_t count;
		long toSkip = dir->seek_position - dir->current_position;
		if (toSkip == dir->entries_left) {
			// we have to skip exactly all of the currently buffered entries
			dir->current_position = dir->seek_position;
			dir->entries_left = 0;
			return 0;
		}

		if (toSkip < dir->entries_left) {
			// we have to skip only some of the buffered entries
			for (; toSkip > 0; toSkip--) {
				struct dirent* entry = (struct dirent*)
					((uint8*)&dir->first_entry + dir->next_entry);
				dir->entries_left--;
				dir->next_entry += entry->d_reclen;
			}

			dir->current_position = dir->seek_position;
			return 0;
		}

		// we have to skip more than the currently buffered entries
		dir->current_position += dir->entries_left;
		dir->entries_left = 0;

		count = _kern_read_dir(dir->fd, &dir->first_entry,
			(char*)dir + DIR_BUFFER_SIZE - (char*)&dir->first_entry, USHRT_MAX);
		if (count <= 0) {
			if (count < 0)
				__set_errno(count);

			// end of directory
			return -1;
		}

		dir->next_entry = 0;
		dir->entries_left = count;
	}

	return 0;
}