Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
static int
fuse_unlink(const char* path)
{
	PRINTD("##unlink\n");
	return _ERR(_kern_unlink(-1, path));
}
Ejemplo n.º 3
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;
}