Example #1
0
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;
}
Example #2
0
File: stat.c Project: mariuz/haiku
int
_lstat_current(const char* path, struct stat* stat)
{
	int status = _kern_read_stat(-1, path, false, stat, sizeof(struct stat));

	RETURN_AND_SET_ERRNO(status);
}
Example #3
0
File: stat.c Project: mariuz/haiku
int
_fstat_current(int fd, struct stat* stat)
{
	int status = _kern_read_stat(fd, NULL, false, stat, sizeof(struct stat));

	RETURN_AND_SET_ERRNO(status);
}
Example #4
0
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;
}
Example #5
0
/*! \brief Fills in the given stat structure with \code stat() \endcode
		   information for this object.
	\param st a pointer to a stat structure to be filled in
	\return
	- \c B_OK: Everything went fine.
	- \c B_BAD_VALUE: \c NULL \a st.
	- another error code, e.g., if the object wasn't properly initialized
*/
status_t
BNode::GetStat(struct stat *st) const
{
	return (fCStatus != B_OK)
		? fCStatus
		: _kern_read_stat(fFd, NULL, false, st, sizeof(struct stat));
}
Example #6
0
File: stat.c Project: mariuz/haiku
int
fstatat(int fd, const char *path, struct stat *st, int flag)
{
	int status = _kern_read_stat(fd, path, (flag & AT_SYMLINK_NOFOLLOW) == 0,
		st, sizeof(struct stat));

	RETURN_AND_SET_ERRNO(status);
}
Example #7
0
static fssh_dev_t
get_volume_id()
{
	struct fssh_stat st;
	fssh_status_t error = _kern_read_stat(-1, kMountPoint, false, &st,
		sizeof(st));
	if (error != FSSH_B_OK)
		return error;
	return st.fssh_st_dev;
}
Example #8
0
dev_t
dev_for_path(const char *path)
{
	struct stat stat;
	int status = _kern_read_stat(-1, path, true, &stat, sizeof(struct stat));
	if (status == B_OK)
		return stat.st_dev;

	RETURN_AND_SET_ERRNO(status);
}
Example #9
0
int
fuse_getattr(const char* path, struct stat* stbuf)
{
	PRINTD("##getattr\n");
	struct fssh_stat f_stbuf;
	fssh_status_t status = _kern_read_stat(-1, path, false, &f_stbuf,
			sizeof(f_stbuf));
	fromFsshStatToStat(&f_stbuf, stbuf);
	if (gIsDebug)
		printf("GETATTR returned: %d\n", status);
	return _ERR(status);
}
Example #10
0
static fssh_dev_t
get_volume_id()
{
	struct fssh_stat st;
	fssh_status_t error = _kern_read_stat(-1, kMountPoint, false, &st,
		sizeof(st));
	if (error != FSSH_B_OK) {
		fprintf(stderr, "Error: Failed to stat() mount point: %s\n",
			fssh_strerror(error));
		return error;
	}

	return st.fssh_st_dev;
}
Example #11
0
status_t
BDirectory::_GetStatFor(const char* path, struct stat* st) const
{
	if (!st)
		return B_BAD_VALUE;
	if (InitCheck() != B_OK)
		return B_NO_INIT;

	if (path != NULL) {
		if (path[0] == '\0')
			return B_ENTRY_NOT_FOUND;
		return _kern_read_stat(fDirFd, path, false, st, sizeof(struct stat));
	}
	return GetStat(st);
}
Example #12
0
static fssh_status_t
remove_entry(int dir, const char *entry, bool recursive, bool force)
{
	// stat the file
	struct fssh_stat st;
	fssh_status_t error = _kern_read_stat(dir, entry, false, &st, sizeof(st));
	if (error != FSSH_B_OK) {
		if (force && error == FSSH_B_ENTRY_NOT_FOUND)
			return FSSH_B_OK;

		fprintf(stderr, "Error: Failed to remove \"%s\": %s\n", entry,
			fssh_strerror(error));
		return error;
	}

	if (FSSH_S_ISDIR(st.fssh_st_mode)) {
		if (!recursive) {
			fprintf(stderr, "Error: \"%s\" is a directory.\n", entry);
				// TODO: get the full path
			return FSSH_EISDIR;
		}

		// remove the contents
		error = remove_dir_contents(dir, entry, force);
		if (error != FSSH_B_OK)
			return error;

		// remove the directory
		error = _kern_remove_dir(dir, entry);
		if (error != FSSH_B_OK) {
			fprintf(stderr, "Error: Failed to remove directory \"%s\": %s\n",
				entry, fssh_strerror(error));
			return error;
		}
	} else {
		// remove the entry
		error = _kern_unlink(dir, entry);
		if (error != FSSH_B_OK) {
			fprintf(stderr, "Error: Failed to remove entry \"%s\": %s\n", entry,
				fssh_strerror(error));
			return error;
		}
	}

	return FSSH_B_OK;
}
Example #13
0
static fssh_status_t
move_entry(int dir, const char *entry, int targetDir, const char* target,
	bool force)
{
	// stat the file
	struct fssh_stat st;
	fssh_status_t status = _kern_read_stat(dir, entry, false, &st, sizeof(st));
	if (status != FSSH_B_OK) {
		if (force && status == FSSH_B_ENTRY_NOT_FOUND)
			return FSSH_B_OK;

		fprintf(stderr, "Error: Failed to move \"%s\": %s\n", entry,
			fssh_strerror(status));
		return status;
	}

	return _kern_rename(dir, entry, targetDir, target);
}
Example #14
0
static int
search_executable_in_path_list(const char *name, const char *pathList,
	int pathListLen, const char *programPath, const char *compatibilitySubDir,
	char *pathBuffer, size_t pathBufferLength)
{
	const char *pathListEnd = pathList + pathListLen;
	status_t status = B_ENTRY_NOT_FOUND;

	TRACE(("runtime_loader: search_container_in_path_list() %s in %.*s\n", name,
		pathListLen, pathList));

	while (pathListLen > 0) {
		const char *pathEnd = pathList;
		int fd;

		// find the next ':' or run till the end of the string
		while (pathEnd < pathListEnd && *pathEnd != ':')
			pathEnd++;

		fd = try_open_executable(pathList, pathEnd - pathList, name,
			programPath, compatibilitySubDir, pathBuffer, pathBufferLength);
		if (fd >= 0) {
			// see if it's a dir
			struct stat stat;
			status = _kern_read_stat(fd, NULL, true, &stat, sizeof(struct stat));
			if (status == B_OK) {
				if (!S_ISDIR(stat.st_mode))
					return fd;
				status = B_IS_A_DIRECTORY;
			}
			_kern_close(fd);
		}

		pathListLen = pathListEnd - pathEnd - 1;
		pathList = pathEnd + 1;
	}

	return status;
}
Example #15
0
static fssh_status_t
command_ln(int argc, const char* const* argv)
{
	bool force = false;
	bool symbolic = false;
	bool dereference = true;

	// parse parameters
	int argi = 1;
	for (argi = 1; argi < argc; argi++) {
		const char *arg = argv[argi];
		if (arg[0] != '-')
			break;

		if (arg[1] == '\0') {
			fprintf(stderr, "Error: Invalid option \"-\"\n");
			return FSSH_B_BAD_VALUE;
		}

		for (int i = 1; arg[i]; i++) {
			switch (arg[i]) {
				case 'f':
					force = true;
					break;
				case 's':
					symbolic = true;
					break;
				case 'n':
					dereference = false;
					break;
				default:
					fprintf(stderr, "Error: Unknown option \"-%c\"\n", arg[i]);
					return FSSH_B_BAD_VALUE;
			}
		}
	}

	if (argc - argi != 2) {
		fprintf(stderr, "Usage: %s [Options] <source> <target>\n", argv[0]);
		return FSSH_B_BAD_VALUE;
	}

	const char *source = argv[argi];
	const char *target = argv[argi + 1];

	// check, if the the target is an existing directory
	struct fssh_stat st;
	char targetBuffer[FSSH_B_PATH_NAME_LENGTH];
	fssh_status_t error = _kern_read_stat(-1, target, dereference, &st,
		sizeof(st));
	if (error == FSSH_B_OK) {
		if (FSSH_S_ISDIR(st.fssh_st_mode)) {
			// get source leaf
			char leaf[FSSH_B_FILE_NAME_LENGTH];
			error = get_last_path_component(source, leaf, sizeof(leaf));
			if (error != FSSH_B_OK) {
				fprintf(stderr, "Error: Failed to get leaf name of source "
					"path: %s\n", fssh_strerror(error));
				return error;
			}

			// compose a new path
			int len = strlen(target) + 1 + strlen(leaf);
			if (len > (int)sizeof(targetBuffer)) {
				fprintf(stderr, "Error: Resulting target path is too long.\n");
				return FSSH_B_BAD_VALUE;
			}

			strcpy(targetBuffer, target);
			strcat(targetBuffer, "/");
			strcat(targetBuffer, leaf);
			target = targetBuffer;
		}
	}

	// check, if the target exists
	error = _kern_read_stat(-1, target, false, &st, sizeof(st));
	if (error == FSSH_B_OK) {
		if (!force) {
			fprintf(stderr, "Error: Can't create link. \"%s\" is in the way.\n",
				target);
			return FSSH_B_FILE_EXISTS;
		}

		// unlink the entry
		error = _kern_unlink(-1, target);
		if (error != FSSH_B_OK) {
			fprintf(stderr, "Error: Failed to remove \"%s\" to make way for "
				"link: %s\n", target, fssh_strerror(error));
			return error;
		}
	}

	// finally create the link
	if (symbolic) {
		error = _kern_create_symlink(-1, target, source,
			FSSH_S_IRWXU | FSSH_S_IRWXG | FSSH_S_IRWXO);
	} else
		error = _kern_create_link(target, source);

	if (error != FSSH_B_OK) {
		fprintf(stderr, "Error: Failed to create link: %s\n",
			fssh_strerror(error));
	}

	return error;
}
Example #16
0
void
register_image(image_t* image, int fd, const char* path)
{
	struct stat stat;
	image_info info;

	// TODO: set these correctly
	info.id = 0;
	info.type = image->type;
	info.sequence = 0;
	info.init_order = 0;
	info.init_routine = (void (*)())image->init_routine;
	info.term_routine = (void (*)())image->term_routine;

	if (_kern_read_stat(fd, NULL, false, &stat, sizeof(struct stat)) == B_OK) {
		info.device = stat.st_dev;
		info.node = stat.st_ino;
	} else {
		info.device = -1;
		info.node = -1;
	}

	// We may have split segments into separate regions. Compute the correct
	// segments for the image info.
	addr_t textBase = 0;
	addr_t textEnd = 0;
	addr_t dataBase = 0;
	addr_t dataEnd = 0;
	for (uint32 i= 0; i < image->num_regions; i++) {
		addr_t base = image->regions[i].vmstart;
		addr_t end = base + image->regions[i].vmsize;
		if (image->regions[i].flags & RFLAG_RW) {
			// data
			if (dataBase == 0) {
				dataBase = base;
				dataEnd = end;
			} else {
				dataBase = std::min(dataBase, base);
				dataEnd = std::max(dataEnd, end);
			}
		} else {
			// text
			if (textBase == 0) {
				textBase = base;
				textEnd = end;
			} else {
				textBase = std::min(textBase, base);
				textEnd = std::max(textEnd, end);
			}
		}
	}

	strlcpy(info.name, path, sizeof(info.name));
	info.text = (void*)textBase;
	info.text_size = textEnd - textBase;
	info.data = (void*)dataBase;
	info.data_size = dataEnd - dataBase;
	info.api_version = image->api_version;
	info.abi = image->abi;
	image->id = _kern_register_image(&info, sizeof(image_info));
}
Example #17
0
static int
try_open_executable(const char *dir, int dirLength, const char *name,
	const char *programPath, const char *compatibilitySubDir, char *path,
	size_t pathLength)
{
	size_t nameLength = strlen(name);
	struct stat stat;
	status_t status;

	// construct the path
	if (dirLength > 0) {
		char *buffer = path;
		size_t subDirLen = 0;

		if (programPath == NULL)
			programPath = gProgramArgs->program_path;

		if (dirLength >= 2 && strncmp(dir, "%A", 2) == 0) {
			// Replace %A with current app folder path (of course,
			// this must be the first part of the path)
			char *lastSlash = strrchr(programPath, '/');
			int bytesCopied;

			// copy what's left (when the application name is removed)
			if (lastSlash != NULL) {
				strlcpy(buffer, programPath,
					std::min((long)pathLength, lastSlash + 1 - programPath));
			} else
				strlcpy(buffer, ".", pathLength);

			bytesCopied = strlen(buffer);
			buffer += bytesCopied;
			pathLength -= bytesCopied;
			dir += 2;
			dirLength -= 2;
		} else if (compatibilitySubDir != NULL) {
			// We're looking for a library or an add-on and the executable has
			// not been compiled with a compiler compatible with the one the
			// OS has been built with. Thus we only look in specific subdirs.
			subDirLen = strlen(compatibilitySubDir) + 1;
		}

		if (dirLength + 1 + subDirLen + nameLength >= pathLength)
			return B_NAME_TOO_LONG;

		memcpy(buffer, dir, dirLength);
		buffer[dirLength] = '/';
		if (subDirLen > 0) {
			memcpy(buffer + dirLength + 1, compatibilitySubDir, subDirLen - 1);
			buffer[dirLength + subDirLen] = '/';
		}
		strcpy(buffer + dirLength + 1 + subDirLen, name);
	} else {
		if (nameLength >= pathLength)
			return B_NAME_TOO_LONG;

		strcpy(path + dirLength + 1, name);
	}

	TRACE(("runtime_loader: try_open_container(): %s\n", path));

	// Test if the target is a symbolic link, and correct the path in this case

	status = _kern_read_stat(-1, path, false, &stat, sizeof(struct stat));
	if (status < B_OK)
		return status;

	if (S_ISLNK(stat.st_mode)) {
		char buffer[PATH_MAX];
		size_t length = PATH_MAX - 1;
		char *lastSlash;

		// it's a link, indeed
		status = _kern_read_link(-1, path, buffer, &length);
		if (status < B_OK)
			return status;
		buffer[length] = '\0';

		lastSlash = strrchr(path, '/');
		if (buffer[0] != '/' && lastSlash != NULL) {
			// relative path
			strlcpy(lastSlash + 1, buffer, lastSlash + 1 - path + pathLength);
		} else
			strlcpy(path, buffer, pathLength);
	}

	return _kern_open(-1, path, O_RDONLY, 0);
}
Example #18
0
static fssh_status_t
command_mv(int argc, const char* const* argv)
{
	bool force = false;

	// parse parameters
	int argi = 1;
	for (argi = 1; argi < argc; argi++) {
		const char *arg = argv[argi];
		if (arg[0] != '-')
			break;

		if (arg[1] == '\0') {
			fprintf(stderr, "Error: Invalid option \"-\"\n");
			return FSSH_B_BAD_VALUE;
		}

		for (int i = 1; arg[i]; i++) {
			switch (arg[i]) {
				case 'f':
					force = true;
					break;
				default:
					fprintf(stderr, "Error: Unknown option \"-%c\"\n", arg[i]);
					return FSSH_B_BAD_VALUE;
			}
		}
	}

	// check params
	int count = argc - 1 - argi;
	if (count <= 0) {
		fprintf(stderr, "Usage: %s [-f] <file>... <target>\n", argv[0]);
		return FSSH_B_BAD_VALUE;
	}

	const char* target = argv[argc - 1];

	// stat the target
	struct fssh_stat st;
	fssh_status_t status = _kern_read_stat(-1, target, true, &st, sizeof(st));
	if (status != FSSH_B_OK && count != 1) {
		fprintf(stderr, "Error: Failed to stat target \"%s\": %s\n", target,
			fssh_strerror(status));
		return status;
	}

	if (status == FSSH_B_OK && FSSH_S_ISDIR(st.fssh_st_mode)) {
		// move several entries
		int targetDir = _kern_open_dir(-1, target);
		if (targetDir < 0) {
			fprintf(stderr, "Error: Failed to open dir \"%s\": %s\n", target,
				fssh_strerror(targetDir));
			return targetDir;
		}

		// move loop
		for (; argi < argc - 1; argi++) {
			status = move_entry(-1, argv[argi], targetDir, argv[argi], force);
			if (status != FSSH_B_OK) {
				_kern_close(targetDir);
				return status;
			}
		}

		_kern_close(targetDir);
		return FSSH_B_OK;
	}

	// rename single entry
	return move_entry(-1, argv[argi], -1, target, force);
}
Example #19
0
static void
list_entry(const char* file, const char* name = NULL)
{
	// construct path, if a leaf name is given
	std::string path;
	if (name) {
		path = file;
		path += '/';
		path += name;
		file = path.c_str();
	} else
		name = file;

	// stat the 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));
		return;
	}

	// get time
	struct tm time;
	time_t fileTime = st.fssh_st_mtime;
	localtime_r(&fileTime, &time);

	// get permissions
	std::string permissions;
	fssh_mode_t mode = st.fssh_st_mode;
	// user
	permissions += ((mode & FSSH_S_IRUSR) ? 'r' : '-');
	permissions += ((mode & FSSH_S_IWUSR) ? 'w' : '-');
	if (mode & FSSH_S_ISUID)
		permissions += 's';
	else
		permissions += ((mode & FSSH_S_IXUSR) ? 'x' : '-');
	// group
	permissions += ((mode & FSSH_S_IRGRP) ? 'r' : '-');
	permissions += ((mode & FSSH_S_IWGRP) ? 'w' : '-');
	if (mode & FSSH_S_ISGID)
		permissions += 's';
	else
		permissions += ((mode & FSSH_S_IXGRP) ? 'x' : '-');
	// others
	permissions += ((mode & FSSH_S_IROTH) ? 'r' : '-');
	permissions += ((mode & FSSH_S_IWOTH) ? 'w' : '-');
	permissions += ((mode & FSSH_S_IXOTH) ? 'x' : '-');

	// get file type
	char fileType = '?';
	if (FSSH_S_ISREG(mode)) {
		fileType = '-';
	} else if (FSSH_S_ISLNK(mode)) {
		fileType = 'l';
	} else if (FSSH_S_ISBLK(mode)) {
		fileType = 'b';
	} else if (FSSH_S_ISDIR(mode)) {
		fileType = 'd';
	} else if (FSSH_S_ISCHR(mode)) {
		fileType = 'c';
	} else if (FSSH_S_ISFIFO(mode)) {
		fileType = 'f';
	} else if (FSSH_S_ISINDEX(mode)) {
		fileType = 'i';
	}

	// get link target
	std::string nameSuffix;
	if (FSSH_S_ISLNK(mode)) {
		char buffer[FSSH_B_PATH_NAME_LENGTH];
		fssh_size_t size = sizeof(buffer) - 1;
		error = _kern_read_link(-1, file, buffer, &size);
		if (error != FSSH_B_OK)
			snprintf(buffer, sizeof(buffer), "(%s)", fssh_strerror(error));

		buffer[size] = '\0';
		nameSuffix += " -> ";
		nameSuffix += buffer;
	}

	printf("%c%s %2d %2d %10" FSSH_B_PRIdOFF
		" %d-%02d-%02d %02d:%02d:%02d %s%s\n",
		fileType, permissions.c_str(), (int)st.fssh_st_uid, (int)st.fssh_st_gid,
		st.fssh_st_size,
		1900 + time.tm_year, 1 + time.tm_mon, time.tm_mday,
		time.tm_hour, time.tm_min, time.tm_sec,
		name, nameSuffix.c_str());
}
Example #20
0
static fssh_status_t
create_dir(const char *path, bool createParents)
{
	// stat the entry
	struct fssh_stat st;
	fssh_status_t error = _kern_read_stat(-1, path, false, &st, sizeof(st));
	if (error == FSSH_B_OK) {
		if (createParents && FSSH_S_ISDIR(st.fssh_st_mode))
			return FSSH_B_OK;

		fprintf(stderr, "Error: Cannot make dir, entry \"%s\" is in the way.\n",
			path);
		return FSSH_B_FILE_EXISTS;
	}

	// the dir doesn't exist yet
	// if we shall create all parents, do that first
	if (createParents) {
		// create the parent dir path
		// eat the trailing '/'s
		int len = strlen(path);
		while (len > 0 && path[len - 1] == '/')
			len--;

		// eat the last path component
		while (len > 0 && path[len - 1] != '/')
			len--;

		// eat the trailing '/'s
		while (len > 0 && path[len - 1] == '/')
			len--;

		// Now either nothing remains, which means we had a single component,
		// a root subdir -- in those cases we can just fall through (we should
		// actually never be here in case of the root dir, but anyway) -- or
		// there is something left, which we can call a parent directory and
		// try to create it.
		if (len > 0) {
			char *parentPath = (char*)malloc(len + 1);
			if (!parentPath) {
				fprintf(stderr, "Error: Failed to allocate memory for parent "
					"path.\n");
				return FSSH_B_NO_MEMORY;
			}
			memcpy(parentPath, path, len);
			parentPath[len] = '\0';

			error = create_dir(parentPath, createParents);

			free(parentPath);

			if (error != FSSH_B_OK)
				return error;
		}
	}

	// make the directory
	error = _kern_create_dir(-1,
		path, (FSSH_S_IRWXU | FSSH_S_IRWXG | FSSH_S_IRWXO) & ~sUmask);
	if (error != FSSH_B_OK) {
		fprintf(stderr, "Error: Failed to make directory \"%s\": %s\n", path,
			fssh_strerror(error));
		return error;
	}

	return FSSH_B_OK;
}