aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/sys.c
blob: 643f327f5b73d1352fede1e176e4a8ac13c9156f (plain)
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
#include "rc.h"

// -----------------------------------------------------------------------
// internal

static
char**
mkargv(Word *args)
{
    char **argv=emalloc((count(args)+2)*sizeof(char *));
    char **argp=argv+1;	/* leave one at front for runcoms */

    for(;args;args=args->link) 
        *argp++=args->str;
    *argp=nil;

    return argv;
}

static
Word*
envval(char *s)
{
    Word *v;
    char *t, c;

    for(t=s; *t && *t!='\1'; t++)
        ;

    c  = *t;
    *t = '\0';

    v = makeword(s, (c=='\0') ? nil : envval(t+1));
    *t=c;

    return v;
}

// -----------------------------------------------------------------------
// exported

void
initenv(void)
{
    extern char **environ;

    char *s;
    char **env;

    for(env=environ; *env; env++) {
        for(s=*env; *s && *s != '(' && *s != '='; s++)
            ;
        switch(*s){
        case '\0':
            break;
        case '(': /* ignore functions */
            break;
        case '=':
            *s = '\0';
            setvar(*env, envval(s+1));
            *s = '=';
            break;
        }
    }
}

void
execute(Word *cmd, Word *path)
{
    int nc;
    char **argv = mkargv(cmd);
    char **env  = mkenv();
    char file[1024];

    for(; path; path=path->link){
        nc = strlen(path->str);
        if(nc < arrlen(file)){
            strcpy(file, path->str);
            if(*file){
                strcat(file, "/");
                nc++;
            }
            if(nc+strlen(argv[1]) < 1024){
                strcat(file, argv[1]);
                execve(file, argv+1, env);
            }else
                fatal("command name too long");
        }
    }
    efree(argv);
    fatal("failed to exec\n");
}