]> git.ipfire.org Git - people/ms/pakfire.git/blame - src/libpakfire/jail.c
jail: Set some default 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 30
d5bc8fe0
MT
31// The default environment that will be set for every command
32static const struct environ {
33 const char* key;
34 const char* val;
35} ENV[] = {
36 { "LANG", "en_US.utf-8" },
37 { "TERM", "vt100" },
38 { NULL, NULL },
39};
40
fd37ccaf
MT
41struct pakfire_jail {
42 struct pakfire* pakfire;
43 int nrefs;
32d5f21d
MT
44
45 // Environment
46 char* env[ENVIRON_SIZE];
fd37ccaf
MT
47};
48
d5bc8fe0
MT
49static void pakfire_jail_free(struct pakfire_jail* jail) {
50 DEBUG(jail->pakfire, "Freeing jail at %p\n", jail);
51
52 // Free environment
53 for (unsigned int i = 0; jail->env[i]; i++)
54 free(jail->env[i]);
55
56 pakfire_unref(jail->pakfire);
57 free(jail);
58}
59
fd37ccaf 60int pakfire_jail_create(struct pakfire_jail** jail, struct pakfire* pakfire) {
d5bc8fe0
MT
61 int r;
62
63 // Allocate a new jail
fd37ccaf
MT
64 struct pakfire_jail* j = calloc(1, sizeof(*j));
65 if (!j)
66 return 1;
67
68 // Reference Pakfire
69 j->pakfire = pakfire_ref(pakfire);
70
71 // Initialize reference counter
72 j->nrefs = 1;
73
84bd7655
MT
74 DEBUG(j->pakfire, "Allocated new jail at %p\n", j);
75
d5bc8fe0
MT
76 // Set default environment
77 for (const struct environ* e = ENV; e->key; e++) {
78 r = pakfire_jail_set_env(j, e->key, e->val);
79 if (r)
80 goto ERROR;
81 }
82
fd37ccaf
MT
83 // Done
84 *jail = j;
85 return 0;
84bd7655 86
d5bc8fe0
MT
87ERROR:
88 pakfire_jail_free(j);
32d5f21d 89
d5bc8fe0 90 return r;
fd37ccaf
MT
91}
92
93struct pakfire_jail* pakfire_jail_ref(struct pakfire_jail* jail) {
94 ++jail->nrefs;
95
96 return jail;
97}
98
99struct pakfire_jail* pakfire_jail_unref(struct pakfire_jail* jail) {
100 if (--jail->nrefs > 0)
101 return jail;
102
103 pakfire_jail_free(jail);
104 return NULL;
105}
32d5f21d
MT
106
107// Environment
108
109// Returns the length of the environment
110static unsigned int pakfire_jail_env_length(struct pakfire_jail* jail) {
111 unsigned int i = 0;
112
113 // Count everything in the environment
114 for (char** e = jail->env; *e; e++)
115 i++;
116
117 return i;
118}
119
120// Finds an existing environment variable and returns its index or -1 if not found
121static int pakfire_jail_find_env(struct pakfire_jail* jail, const char* key) {
122 if (!key) {
123 errno = EINVAL;
124 return -1;
125 }
126
127 char buffer[strlen(key) + 2];
128 pakfire_string_format(buffer, "%s=", key);
129
130 for (unsigned int i = 0; jail->env[i]; i++) {
131 if (pakfire_string_startswith(jail->env[i], buffer))
132 return i;
133 }
134
135 // Nothing found
136 return -1;
137}
138
139// Returns the value of an environment variable or NULL
140const char* pakfire_jail_get_env(struct pakfire_jail* jail, const char* key) {
141 int i = pakfire_jail_find_env(jail, key);
142 if (i < 0)
143 return NULL;
144
145 return jail->env[i] + strlen(key) + 1;
146}
147
148// Sets an environment variable
149int pakfire_jail_set_env(struct pakfire_jail* jail, const char* key, const char* value) {
150 // Find the index where to write this value to
151 int i = pakfire_jail_find_env(jail, key);
152 if (i < 0)
153 i = pakfire_jail_env_length(jail);
154
155 // Return -ENOSPC when the environment is full
156 if (i >= ENVIRON_SIZE) {
157 errno = ENOSPC;
158 return -1;
159 }
160
161 // Free any previous value
162 if (jail->env[i])
163 free(jail->env[i]);
164
165 // Format and set environment variable
166 asprintf(&jail->env[i], "%s=%s", key, value);
167
168 DEBUG(jail->pakfire, "Set environment variable: %s\n", jail->env[i]);
169
170 return 0;
171}