~linuxhackerman/iwd

9358db389e8a3f208e46b221dd45e3f6bb62226c — Linus Heckemann 1 year, 2 months ago 7d2e530
declarative check improvements:

- factor declarative checking out into separate procedure
- load declarative networks only once
- use basename of network files instead of full path
2 files changed, 81 insertions(+), 22 deletions(-)

M src/dbus.c
M src/network.c
M src/dbus.c => src/dbus.c +1 -1
@@ 114,7 114,7 @@ struct l_dbus_message *dbus_error_not_supported(struct l_dbus_message *msg)
					"Operation not supported");
}

struct l_dbus_message *dbus_error_file_is_a_nix_store_path(struct l_dbus_message *msg, char *ssid)
struct l_dbus_message *dbus_error_configured_by_nixos(struct l_dbus_message *msg, char *ssid)
{
	return l_dbus_message_new_error(msg, IWD_SERVICE ".NotSupportNixOS",
					"Cannot update SSID %s as it is configured statically by NixOS. Please update your NixOS config accordingly.", ssid);

M src/network.c => src/network.c +80 -21
@@ 54,6 54,58 @@
static uint32_t known_networks_watch;
static uint32_t anqp_watch;


struct list;
typedef struct list {
	struct list* next;
	const char* data;
} list;

static list *prepend(list *in, const char *data) {
	list *ret = calloc(1, sizeof(list));
	ret->next = in;
	ret->data = data;
	return ret;
};

static list *declarative_networks = NULL;

static void load_declarative_networks(void)
{
	if (declarative_networks) {
		return;
	}

	FILE *handle = fopen("/var/lib/iwd/.declarative-nixos-networks", "r");
	if (!handle) {
		// A list containing only NULL indicates that we have no NixOS-configured networks.
		declarative_networks = prepend(declarative_networks, NULL);
		return;
	}

	size_t line_size = 0;
	char *line = NULL;
	char *filename;

	while (getline(&line, &line_size, handle) != -1) {
		// Remove trailing newline
		*index(line, '\n') = '\0';

		filename = rindex(line, '/');
		if (filename) {
			filename++;
		} else {
			filename = line;
		}

		declarative_networks = prepend(declarative_networks, strdup(filename));
	}

	free(line);
	fclose(handle);
}


struct network {
	char ssid[33];
	enum security security;


@@ 79,6 131,32 @@ struct network {
	struct l_dbus_message *connect_after_anqp;
};


static bool check_declarative_network(const struct network *network)
{
	if (network->info == NULL) {
		return false;
	}

	load_declarative_networks();

	char *cfgpath = network->info->ops->get_file_path(network->info);

	char *filename = rindex(cfgpath, '/');
	if (filename) {
		filename++;
	} else {
		filename = cfgpath;
	}

	for (list *check = declarative_networks; check; check = check->next) {
		if (check->data && strcmp(check->data, filename) == 0) {
			return true;
		}
	}
	return false;
}

static bool network_settings_load(struct network *network)
{
	if (network->settings)


@@ 853,27 931,8 @@ static struct l_dbus_message *network_connect_psk(struct network *network,
		network->ask_passphrase ? "true" : "false");

	if (network->ask_passphrase) {
		FILE *handle;
		handle = fopen("/var/lib/iwd/.declarative-nixos-networks", "r");
		char *line = NULL;
		size_t at = 0;
		if (handle != NULL && network->info != NULL) {
			char *cfgpath_ = network->info->ops->get_file_path(network->info);
			char cfgpath[PATH_MAX];
			if (realpath(cfgpath_, cfgpath) != NULL) {
				char tocheck[PATH_MAX];
				while (getline(&line, &at, handle) != -1) {
					*index(line, '\n') = '\0';
					snprintf(tocheck, PATH_MAX - 1, "/var/lib/iwd/%s", line);
					if (strcmp(tocheck, cfgpath) == 0) {
						free(line);
						fclose(handle);
						return dbus_error_file_is_a_nix_store_path(message, network->ssid);
					}
				}
			}
			free(line);
			fclose(handle);
		if (check_declarative_network(network)) {
			return dbus_error_configured_by_nixos(message, network->ssid);
		}

		network->ask_passphrase = false;