# #
#############################################################################*/
+#include <errno.h>
+#include <stdlib.h>
+
#include <pakfire/logging.h>
#include <pakfire/jail.h>
#include <pakfire/pakfire.h>
+#include <pakfire/util.h>
+
+#define ENVIRON_SIZE 128
struct pakfire_jail {
struct pakfire* pakfire;
int nrefs;
+
+ // Environment
+ char* env[ENVIRON_SIZE];
};
int pakfire_jail_create(struct pakfire_jail** jail, struct pakfire* pakfire) {
static void pakfire_jail_free(struct pakfire_jail* jail) {
DEBUG(jail->pakfire, "Freeing jail at %p\n", jail);
+ // Free environment
+ for (unsigned int i = 0; jail->env[i]; i++)
+ free(jail->env[i]);
+
pakfire_unref(jail->pakfire);
free(jail);
}
pakfire_jail_free(jail);
return NULL;
}
+
+// Environment
+
+// Returns the length of the environment
+static unsigned int pakfire_jail_env_length(struct pakfire_jail* jail) {
+ unsigned int i = 0;
+
+ // Count everything in the environment
+ for (char** e = jail->env; *e; e++)
+ i++;
+
+ return i;
+}
+
+// Finds an existing environment variable and returns its index or -1 if not found
+static int pakfire_jail_find_env(struct pakfire_jail* jail, const char* key) {
+ if (!key) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ char buffer[strlen(key) + 2];
+ pakfire_string_format(buffer, "%s=", key);
+
+ for (unsigned int i = 0; jail->env[i]; i++) {
+ if (pakfire_string_startswith(jail->env[i], buffer))
+ return i;
+ }
+
+ // Nothing found
+ return -1;
+}
+
+// Returns the value of an environment variable or NULL
+const char* pakfire_jail_get_env(struct pakfire_jail* jail, const char* key) {
+ int i = pakfire_jail_find_env(jail, key);
+ if (i < 0)
+ return NULL;
+
+ return jail->env[i] + strlen(key) + 1;
+}
+
+// Sets an environment variable
+int pakfire_jail_set_env(struct pakfire_jail* jail, const char* key, const char* value) {
+ // Find the index where to write this value to
+ int i = pakfire_jail_find_env(jail, key);
+ if (i < 0)
+ i = pakfire_jail_env_length(jail);
+
+ // Return -ENOSPC when the environment is full
+ if (i >= ENVIRON_SIZE) {
+ errno = ENOSPC;
+ return -1;
+ }
+
+ // Free any previous value
+ if (jail->env[i])
+ free(jail->env[i]);
+
+ // Format and set environment variable
+ asprintf(&jail->env[i], "%s=%s", key, value);
+
+ DEBUG(jail->pakfire, "Set environment variable: %s\n", jail->env[i]);
+
+ return 0;
+}
return EXIT_FAILURE;
}
+static int test_env(const struct test* t) {
+ struct pakfire_jail* jail = NULL;
+
+ // Create a new jail
+ ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
+
+ // Fetch a non-existing environment variable
+ ASSERT_NULL(pakfire_jail_get_env(jail, "VARIABLE"));
+
+ // Set a variable
+ ASSERT_SUCCESS(pakfire_jail_set_env(jail, "VARIABLE", "VALUE"));
+
+ // Read the value back
+ ASSERT_STRING_EQUALS(pakfire_jail_get_env(jail, "VARIABLE"), "VALUE");
+
+ // Destroy it
+ ASSERT_NULL(pakfire_jail_unref(jail));
+
+ return EXIT_SUCCESS;
+
+FAIL:
+ return EXIT_FAILURE;
+}
+
+
int main(int argc, char** argv) {
testsuite_add_test(test_create);
+ testsuite_add_test(test_env);
return testsuite_run();
}