File: newenv.c

package info (click to toggle)
tinyssh 20250501-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,388 kB
  • sloc: ansic: 20,245; sh: 1,582; python: 1,449; makefile: 913
file content (121 lines) | stat: -rw-r--r-- 2,411 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
20140215
20241208 - reformated using clang-format
Jan Mojzis
Public domain.

The 'newenv' library is used to execute process in completely new environment.
*/

#include <unistd.h>
#include "e.h"
#include "byte.h"
#include "str.h"
#include "purge.h"
#include "bug.h"
#include "env.h"
#include "trymlock.h"
#include "newenv.h"

#define NEWENV_LEN 128
#define NEWENV_SPACE 2048

static struct newenv {
    char *e[NEWENV_LEN];
    long long elen;
    char es[NEWENV_SPACE];
    long long eslen;
} n = {{0}, 0, {0}, 0};

/*
Remove sentitive data from allocated memory.
*/
void newenv_purge(void) {
    purge(&n, sizeof n);
    n.elen = NEWENV_LEN;
    n.eslen = NEWENV_SPACE;
    trymunlock(&n, sizeof n);
}

/*
Initialize newenv structure.
*/
void newenv_init(void) {
    trymlock(&n, sizeof n);
    purge(&n, sizeof n);
    n.e[0] = 0;
    n.elen = n.eslen = 0;
}

/*
The 'newenv_env/newenv_lowenv' function adds the variable into new environment.
The newenv_lowenv is limited to a half of the buffer-space.
*/

int newenv_env_(int x, const char *s, const char *t) {

    long long slen, tlen, len, i;

    if (!x || !s || !t) bug_inval();
    if (n.elen < 0) bug_inval();
    if (n.eslen < 0) bug_inval();

    slen = str_len(s);
    tlen = str_len(t);
    len = slen + tlen + 2;

    if (!n.elen) newenv_init();

    for (i = 0; n.e[i]; ++i) {
        if (str_start(n.e[i], s) && (n.e[i][slen] == '=')) {
            n.e[i] = n.e[--n.elen];
            break;
        }
    }

    if (n.elen + 2 > NEWENV_LEN / x) {
        errno = ENOMEM;
        return 0;
    }
    if (n.eslen + len > NEWENV_SPACE / x) {
        errno = ENOMEM;
        return 0;
    }

    byte_copy(n.es + n.eslen, slen, s);
    n.eslen += slen;
    n.es[n.eslen++] = '=';
    byte_copy(n.es + n.eslen, tlen, t);
    n.eslen += tlen;
    n.es[n.eslen++] = 0;
    n.e[n.elen++] = n.es + n.eslen - len;
    n.e[n.elen] = 0;
    return 1;
}

/*
The 'newenv_copyenv' function copies the variable from current environment into
new environment.
*/
int newenv_copyenv(const char *s) {

    char *t;

    if (!s) bug_inval();

    t = env_get(s);
    if (!t) {
        errno = ENOENT;
        return 0;
    }

    return newenv_env_(1, s, t);
}

/*
The 'newenv_exec' function executes the command in new environment.
*/
void newenv_exec(char *filename, char **argv) {
    if (!argv || !filename) bug_inval();
    execve(filename, argv, n.e);
}