<commit_before>#include <gio/gio.h>
#include <string.h>

#include "config_file.h"
#include "context.h"
#include "network.h"
#include "signature.h"

RaucContext *context = NULL;

static const gchar* get_cmdline_bootname(void)
{
	GRegex *regex = NULL;
	GMatchInfo *match = NULL;
	char *contents = NULL;
	static const char *bootname = NULL;
	gchar buf[PATH_MAX + 1];
	gchar *realdev = NULL;

	if (bootname != NULL)
		return bootname;

	if (!g_file_get_contents("/proc/cmdline", &contents, NULL, NULL))
		return NULL;

	regex = g_regex_new("rauc\\.slot=(\\S+)", 0, 0, NULL);
	if (g_regex_match(regex, contents, 0, &match)) {
		bootname = g_match_info_fetch(match, 1);
		goto out;
	}
	g_clear_pointer(&match, g_match_info_free);
	g_clear_pointer(&regex, g_regex_unref);

	/* For barebox, we check if the bootstate code set the active slot name
	 * in the command line */
	if (g_strcmp0(context->config->system_bootloader, "barebox") == 0) {
		regex = g_regex_new("(?:bootstate|bootchooser)\\.active=(\\S+)", 0, 0, NULL);
		if (g_regex_match(regex, contents, 0, &match)) {
			bootname = g_match_info_fetch(match, 1);
			goto out;
		}
		g_clear_pointer(&match, g_match_info_free);
		g_clear_pointer(&regex, g_regex_unref);
	}

	regex = g_regex_new("root=(\\S+)", 0, 0, NULL);
	if (g_regex_match(regex, contents, 0, &match)) {
		bootname = g_match_info_fetch(match, 1);
	}
	if (!bootname)
		goto out;

	if (strncmp(bootname, "PARTUUID=", 9) == 0) {
		gchar *partuuidpath = g_build_filename(
				"/dev/disk/by-partuuid/",
				&bootname[9],
				NULL);
		if (partuuidpath) {
			g_free((gchar*) bootname);
			bootname = partuuidpath;
		}
	}

	if (strncmp(bootname, "UUID=", 5) == 0) {
		gchar *uuidpath = g_build_filename(
				"/dev/disk/by-uuid/",
				&bootname[5],
				NULL);
		if (uuidpath) {
			g_free((gchar*) bootname);
			bootname = uuidpath;
		}
	}

	realdev = realpath(bootname, buf);
	if (realdev == NULL) {
		g_message("Failed to resolve realpath for '%s'", bootname);
		goto out;
	}

	if (g_strcmp0(realdev, bootname) != 0) {
		g_debug("Resolved bootname %s to %s", bootname, realdev);

		g_free((gchar*) bootname);
		bootname = g_strdup(realdev);
	}


out:
	g_clear_pointer(&match, g_match_info_free);
	g_clear_pointer(&regex, g_regex_unref);
	g_clear_pointer(&contents, g_free);

	return bootname;
}

static gboolean launch_and_wait_variables_handler(gchar *handler_name, GHashTable *variables, GError **error)
{
	GSubprocessLauncher *handlelaunch = NULL;
	GSubprocess *handleproc = NULL;
	GError *ierror = NULL;
	gboolean res = FALSE;
	GHashTableIter iter;
	gchar *key = NULL;
	gchar *value = NULL;
	GDataInputStream *datainstream = NULL;
	GInputStream *instream;
	gchar* outline;<commit_msg>context: split out repeated regex match into function<commit_after>#include <gio/gio.h>
#include <string.h>

#include "config_file.h"
#include "context.h"
#include "network.h"
#include "signature.h"

RaucContext *context = NULL;

static const gchar *regex_match(const gchar *pattern, const gchar *string)
{
	GRegex *regex = NULL;
	GMatchInfo *match = NULL;
	const gchar *result = NULL;

	regex = g_regex_new(pattern, 0, 0, NULL);
	if (g_regex_match(regex, string, 0, &match))
		result = g_match_info_fetch(match, 1);

	g_clear_pointer(&match, g_match_info_free);
	g_clear_pointer(&regex, g_regex_unref);
	return result;
}

static const gchar* get_cmdline_bootname(void)
{
	char *contents = NULL;
	static const char *bootname = NULL;
	gchar buf[PATH_MAX + 1];
	gchar *realdev = NULL;

	if (bootname != NULL)
		return bootname;

	if (!g_file_get_contents("/proc/cmdline", &contents, NULL, NULL))
		return NULL;

	bootname = regex_match("rauc\\.slot=(\\S+)", contents);
	if (bootname)
		goto out;

	/* For barebox, we check if the bootstate code set the active slot name
	 * in the command line */
	if (g_strcmp0(context->config->system_bootloader, "barebox") == 0) {
		bootname = regex_match(
				"(?:bootstate|bootchooser)\\.active=(\\S+)",
				contents);
		if (bootname)
			goto out;
	}

	bootname = regex_match("root=(\\S+)", contents);
	if (!bootname)
		goto out;

	if (strncmp(bootname, "PARTUUID=", 9) == 0) {
		gchar *partuuidpath = g_build_filename(
				"/dev/disk/by-partuuid/",
				&bootname[9],
				NULL);
		if (partuuidpath) {
			g_free((gchar*) bootname);
			bootname = partuuidpath;
		}
	}

	if (strncmp(bootname, "UUID=", 5) == 0) {
		gchar *uuidpath = g_build_filename(
				"/dev/disk/by-uuid/",
				&bootname[5],
				NULL);
		if (uuidpath) {
			g_free((gchar*) bootname);
			bootname = uuidpath;
		}
	}

	realdev = realpath(bootname, buf);
	if (realdev == NULL) {
		g_message("Failed to resolve realpath for '%s'", bootname);
		goto out;
	}

	if (g_strcmp0(realdev, bootname) != 0) {
		g_debug("Resolved bootname %s to %s", bootname, realdev);

		g_free((gchar*) bootname);
		bootname = g_strdup(realdev);
	}


out:
	g_clear_pointer(&contents, g_free);

	return bootname;
}

static gboolean launch_and_wait_variables_handler(gchar *handler_name, GHashTable *variables, GError **error)
{
	GSubprocessLauncher *handlelaunch = NULL;
	GSubprocess *handleproc = NULL;
	GError *ierror = NULL;
	gboolean res = FALSE;
	GHashTableIter iter;
	gchar *key = NULL;
	gchar *value = NULL;
	GDataInputStream *datainstream = NULL;
	GInputStream *instream;
	gchar* outline;
{'fraction_non_alphanumeric': 0.14776828110161444, 'fraction_numerical': 0.007217473884140551, 'mean_word_length': 4.5548523206751055, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6028605', 'n_tokens_mistral': 2172, 'n_tokens_neox': 2006, 'n_words': 471}