]> git.ipfire.org Git - people/ms/pakfire.git/blame - src/libpakfire/jail.c
jail: Implement setting environment variables
[people/ms/pakfire.git] / src / libpakfire / jail.c
CommitLineData
fd37ccaf
MT
1/*#############################################################################
2# #
3# Pakfire - The IPFire package management system #
4# Copyright (C) 2022 Pakfire development team #
5# #
6# This program is free software: you can redistribute it and/or modify #
7# it under the terms of the GNU General Public License as published by #
8# the Free Software Foundation, either version 3 of the License, or #
9# (at your option) any later version. #
10# #
11# This program is distributed in the hope that it will be useful, #
12# but WITHOUT ANY WARRANTY; without even the implied warranty of #
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14# GNU General Public License for more details. #
15# #
16# You should have received a copy of the GNU General Public License #
17# along with this program. If not, see <http://www.gnu.org/licenses/>. #
18# #
19#############################################################################*/
20
32d5f21d
MT
21#include <errno.h>
22#include <stdlib.h>
23
84bd7655 24#include <pakfire/logging.h>
fd37ccaf
MT
25#include <pakfire/jail.h>
26#include <pakfire/pakfire.h>
32d5f21d
MT
27#include <pakfire/util.h>
28
29#define ENVIRON_SIZE 128
fd37ccaf
MT
30
31struct pakfire_jail {
32 struct pakfire* pakfire;
33 int nrefs;
32d5f21d
MT
34
35 // Environment
36 char* env[ENVIRON_SIZE];
fd37ccaf
MT
37};
38
39int pakfire_jail_create(struct pakfire_jail** jail, struct pakfire* pakfire) {
40 struct pakfire_jail* j = calloc(1, sizeof(*j));
41 if (!j)
42 return 1;
43
44 // Reference Pakfire
45 j->pakfire = pakfire_ref(pakfire);
46
47 // Initialize reference counter
48 j->nrefs = 1;
49
84bd7655
MT
50 DEBUG(j->pakfire, "Allocated new jail at %p\n", j);
51
fd37ccaf
MT
52 // Done
53 *jail = j;
54 return 0;
55}
56
57static void pakfire_jail_free(struct pakfire_jail* jail) {
84bd7655
MT
58 DEBUG(jail->pakfire, "Freeing jail at %p\n", jail);
59
32d5f21d
MT
60 // Free environment
61 for (unsigned int i = 0; jail->env[i]; i++)
62 free(jail->env[i]);
63
fd37ccaf
MT
64 pakfire_unref(jail->pakfire);
65 free(jail);
66}
67
68struct pakfire_jail* pakfire_jail_ref(struct pakfire_jail* jail) {
69 ++jail->nrefs;
70
71 return jail;
72}
73
74struct pakfire_jail* pakfire_jail_unref(struct pakfire_jail* jail) {
75 if (--jail->nrefs > 0)
76 return jail;
77
78 pakfire_jail_free(jail);
79 return NULL;
80}
32d5f21d
MT
81
82// Environment
83
84// Returns the length of the environment
85static unsigned int pakfire_jail_env_length(struct pakfire_jail* jail) {
86 unsigned int i = 0;
87
88 // Count everything in the environment
89 for (char** e = jail->env; *e; e++)
90 i++;
91
92 return i;
93}
94
95// Finds an existing environment variable and returns its index or -1 if not found
96static int pakfire_jail_find_env(struct pakfire_jail* jail, const char* key) {
97 if (!key) {
98 errno = EINVAL;
99 return -1;
100 }
101
102 char buffer[strlen(key) + 2];
103 pakfire_string_format(buffer, "%s=", key);
104
105 for (unsigned int i = 0; jail->env[i]; i++) {
106 if (pakfire_string_startswith(jail->env[i], buffer))
107 return i;
108 }
109
110 // Nothing found
111 return -1;
112}
113
114// Returns the value of an environment variable or NULL
115const char* pakfire_jail_get_env(struct pakfire_jail* jail, const char* key) {
116 int i = pakfire_jail_find_env(jail, key);
117 if (i < 0)
118 return NULL;
119
120 return jail->env[i] + strlen(key) + 1;
121}
122
123// Sets an environment variable
124int pakfire_jail_set_env(struct pakfire_jail* jail, const char* key, const char* value) {
125 // Find the index where to write this value to
126 int i = pakfire_jail_find_env(jail, key);
127 if (i < 0)
128 i = pakfire_jail_env_length(jail);
129
130 // Return -ENOSPC when the environment is full
131 if (i >= ENVIRON_SIZE) {
132 errno = ENOSPC;
133 return -1;
134 }
135
136 // Free any previous value
137 if (jail->env[i])
138 free(jail->env[i]);
139
140 // Format and set environment variable
141 asprintf(&jail->env[i], "%s=%s", key, value);
142
143 DEBUG(jail->pakfire, "Set environment variable: %s\n", jail->env[i]);
144
145 return 0;
146}