Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / boot / ficl / loader.c
1 /*-
2  * Copyright (c) 2000 Daniel Capo Sobral
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *      $FreeBSD: src/sys/boot/ficl/loader.c,v 1.1.2.1 2000/07/06 23:44:59 obrien Exp $
27  */
28
29 /*******************************************************************
30 ** l o a d e r . c
31 ** Additional FICL words designed for FreeBSD's loader
32 ** 
33 *******************************************************************/
34
35 #include <stand.h>
36 #include "bootstrap.h"
37 #include <string.h>
38 #include "ficl.h"
39
40 /*              FreeBSD's loader interaction words
41  *
42  *              setenv      ( value n name n' -- )
43  *              setenv?     ( value n name n' flag -- )
44  *              getenv      ( addr n -- addr' n' | -1 )
45  *              unsetenv    ( addr n -- )
46  *              copyin      ( addr addr' len -- )
47  *              copyout     ( addr addr' len -- )
48  */
49
50 void
51 ficlSetenv(FICL_VM *pVM)
52 {
53         char    *namep, *valuep, *name, *value;
54         int     names, values;
55
56 #if FICL_ROBUST > 1
57         vmCheckStack(pVM, 4, 0);
58 #endif
59         names = stackPopINT(pVM->pStack);
60         namep = (char*) stackPopPtr(pVM->pStack);
61         values = stackPopINT(pVM->pStack);
62         valuep = (char*) stackPopPtr(pVM->pStack);
63
64         name = (char*) ficlMalloc(names+1);
65         if (!name)
66                 vmThrowErr(pVM, "Error: out of memory");
67         strncpy(name, namep, names);
68         name[names] = '\0';
69         value = (char*) ficlMalloc(values+1);
70         if (!value)
71                 vmThrowErr(pVM, "Error: out of memory");
72         strncpy(value, valuep, values);
73         value[values] = '\0';
74
75         setenv(name, value, 1);
76         ficlFree(name);
77         ficlFree(value);
78
79         return;
80 }
81
82 void
83 ficlSetenvq(FICL_VM *pVM)
84 {
85         char    *namep, *valuep, *name, *value;
86         int     names, values, overwrite;
87
88 #if FICL_ROBUST > 1
89         vmCheckStack(pVM, 5, 0);
90 #endif
91         overwrite = stackPopINT(pVM->pStack);
92         names = stackPopINT(pVM->pStack);
93         namep = (char*) stackPopPtr(pVM->pStack);
94         values = stackPopINT(pVM->pStack);
95         valuep = (char*) stackPopPtr(pVM->pStack);
96
97         name = (char*) ficlMalloc(names+1);
98         if (!name)
99                 vmThrowErr(pVM, "Error: out of memory");
100         strncpy(name, namep, names);
101         name[names] = '\0';
102         value = (char*) ficlMalloc(values+1);
103         if (!value)
104                 vmThrowErr(pVM, "Error: out of memory");
105         strncpy(value, valuep, values);
106         value[values] = '\0';
107
108         setenv(name, value, overwrite);
109         ficlFree(name);
110         ficlFree(value);
111
112         return;
113 }
114
115 void
116 ficlGetenv(FICL_VM *pVM)
117 {
118         char    *namep, *name, *value;
119         int     names;
120
121 #if FICL_ROBUST > 1
122         vmCheckStack(pVM, 2, 2);
123 #endif
124         names = stackPopINT(pVM->pStack);
125         namep = (char*) stackPopPtr(pVM->pStack);
126
127         name = (char*) ficlMalloc(names+1);
128         if (!name)
129                 vmThrowErr(pVM, "Error: out of memory");
130         strncpy(name, namep, names);
131         name[names] = '\0';
132
133         value = getenv(name);
134         ficlFree(name);
135
136         if(value != NULL) {
137                 stackPushPtr(pVM->pStack, value);
138                 stackPushINT(pVM->pStack, strlen(value));
139         } else
140                 stackPushINT(pVM->pStack, -1);
141
142         return;
143 }
144
145 void
146 ficlUnsetenv(FICL_VM *pVM)
147 {
148         char    *namep, *name;
149         int     names;
150
151 #if FICL_ROBUST > 1
152         vmCheckStack(pVM, 2, 0);
153 #endif
154         names = stackPopINT(pVM->pStack);
155         namep = (char*) stackPopPtr(pVM->pStack);
156
157         name = (char*) ficlMalloc(names+1);
158         if (!name)
159                 vmThrowErr(pVM, "Error: out of memory");
160         strncpy(name, namep, names);
161         name[names] = '\0';
162
163         unsetenv(name);
164         ficlFree(name);
165
166         return;
167 }
168
169 void
170 ficlCopyin(FICL_VM *pVM)
171 {
172         void*           src;
173         vm_offset_t     dest;
174         size_t          len;
175
176 #if FICL_ROBUST > 1
177         vmCheckStack(pVM, 3, 0);
178 #endif
179
180         len = stackPopINT(pVM->pStack);
181         dest = stackPopINT(pVM->pStack);
182         src = stackPopPtr(pVM->pStack);
183
184         archsw.arch_copyin(src, dest, len);
185
186         return;
187 }
188
189 void
190 ficlCopyout(FICL_VM *pVM)
191 {
192         void*           dest;
193         vm_offset_t     src;
194         size_t          len;
195
196 #if FICL_ROBUST > 1
197         vmCheckStack(pVM, 3, 0);
198 #endif
199
200         len = stackPopINT(pVM->pStack);
201         dest = stackPopPtr(pVM->pStack);
202         src = stackPopINT(pVM->pStack);
203
204         archsw.arch_copyout(src, dest, len);
205
206         return;
207 }
208