xref: /freebsd/stand/ficl/loader.c (revision afc571b1a6fb341b0e3f603d4f3a2538093e91f5)
1ca987d46SWarner Losh /*-
2ca987d46SWarner Losh  * Copyright (c) 2000 Daniel Capo Sobral
3ca987d46SWarner Losh  * All rights reserved.
4ca987d46SWarner Losh  *
5ca987d46SWarner Losh  * Redistribution and use in source and binary forms, with or without
6ca987d46SWarner Losh  * modification, are permitted provided that the following conditions
7ca987d46SWarner Losh  * are met:
8ca987d46SWarner Losh  * 1. Redistributions of source code must retain the above copyright
9ca987d46SWarner Losh  *    notice, this list of conditions and the following disclaimer.
10ca987d46SWarner Losh  * 2. Redistributions in binary form must reproduce the above copyright
11ca987d46SWarner Losh  *    notice, this list of conditions and the following disclaimer in the
12ca987d46SWarner Losh  *    documentation and/or other materials provided with the distribution.
13ca987d46SWarner Losh  *
14ca987d46SWarner Losh  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15ca987d46SWarner Losh  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16ca987d46SWarner Losh  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17ca987d46SWarner Losh  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18ca987d46SWarner Losh  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19ca987d46SWarner Losh  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20ca987d46SWarner Losh  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21ca987d46SWarner Losh  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22ca987d46SWarner Losh  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23ca987d46SWarner Losh  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24ca987d46SWarner Losh  * SUCH DAMAGE.
25ca987d46SWarner Losh  *
26ca987d46SWarner Losh  *	$FreeBSD$
27ca987d46SWarner Losh  */
28ca987d46SWarner Losh 
29ca987d46SWarner Losh /*******************************************************************
30ca987d46SWarner Losh ** l o a d e r . c
31ca987d46SWarner Losh ** Additional FICL words designed for FreeBSD's loader
32ca987d46SWarner Losh **
33ca987d46SWarner Losh *******************************************************************/
34ca987d46SWarner Losh 
35ca987d46SWarner Losh #ifdef TESTMAIN
36ca987d46SWarner Losh #include <sys/types.h>
37ca987d46SWarner Losh #include <sys/stat.h>
38ca987d46SWarner Losh #include <dirent.h>
39ca987d46SWarner Losh #include <fcntl.h>
40ca987d46SWarner Losh #include <stdio.h>
41ca987d46SWarner Losh #include <stdlib.h>
42ca987d46SWarner Losh #include <unistd.h>
43ca987d46SWarner Losh #else
44ca987d46SWarner Losh #include <stand.h>
45ca987d46SWarner Losh #endif
46ca987d46SWarner Losh #include "bootstrap.h"
47ca987d46SWarner Losh #include <string.h>
48ca987d46SWarner Losh #include <uuid.h>
49ca987d46SWarner Losh #include "ficl.h"
50ca987d46SWarner Losh 
51ca987d46SWarner Losh /*		FreeBSD's loader interaction words and extras
52ca987d46SWarner Losh  *
53ca987d46SWarner Losh  * 		setenv      ( value n name n' -- )
54ca987d46SWarner Losh  * 		setenv?     ( value n name n' flag -- )
55ca987d46SWarner Losh  * 		getenv      ( addr n -- addr' n' | -1 )
56ca987d46SWarner Losh  * 		unsetenv    ( addr n -- )
57ca987d46SWarner Losh  * 		copyin      ( addr addr' len -- )
58ca987d46SWarner Losh  * 		copyout     ( addr addr' len -- )
59ca987d46SWarner Losh  * 		findfile    ( name len type len' -- addr )
60ca987d46SWarner Losh  * 		pnpdevices  ( -- addr )
61ca987d46SWarner Losh  * 		pnphandlers ( -- addr )
62ca987d46SWarner Losh  * 		ccall       ( [[...[p10] p9] ... p1] n addr -- result )
63ca987d46SWarner Losh  *		uuid-from-string ( addr n -- addr' )
64ca987d46SWarner Losh  *		uuid-to-string ( addr' -- addr n )
65ca987d46SWarner Losh  * 		.#	    ( value -- )
66ca987d46SWarner Losh  */
67ca987d46SWarner Losh 
68ca987d46SWarner Losh void
69ca987d46SWarner Losh ficlSetenv(FICL_VM *pVM)
70ca987d46SWarner Losh {
71ca987d46SWarner Losh #ifndef TESTMAIN
72ca987d46SWarner Losh 	char	*name, *value;
73ca987d46SWarner Losh #endif
74ca987d46SWarner Losh 	char	*namep, *valuep;
75ca987d46SWarner Losh 	int	names, values;
76ca987d46SWarner Losh 
77ca987d46SWarner Losh #if FICL_ROBUST > 1
78ca987d46SWarner Losh 	vmCheckStack(pVM, 4, 0);
79ca987d46SWarner Losh #endif
80ca987d46SWarner Losh 	names = stackPopINT(pVM->pStack);
81ca987d46SWarner Losh 	namep = (char*) stackPopPtr(pVM->pStack);
82ca987d46SWarner Losh 	values = stackPopINT(pVM->pStack);
83ca987d46SWarner Losh 	valuep = (char*) stackPopPtr(pVM->pStack);
84ca987d46SWarner Losh 
85ca987d46SWarner Losh #ifndef TESTMAIN
86ca987d46SWarner Losh 	name = (char*) ficlMalloc(names+1);
87ca987d46SWarner Losh 	if (!name)
88ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
89ca987d46SWarner Losh 	strncpy(name, namep, names);
90ca987d46SWarner Losh 	name[names] = '\0';
91ca987d46SWarner Losh 	value = (char*) ficlMalloc(values+1);
92ca987d46SWarner Losh 	if (!value)
93ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
94ca987d46SWarner Losh 	strncpy(value, valuep, values);
95ca987d46SWarner Losh 	value[values] = '\0';
96ca987d46SWarner Losh 
97ca987d46SWarner Losh 	setenv(name, value, 1);
98ca987d46SWarner Losh 	ficlFree(name);
99ca987d46SWarner Losh 	ficlFree(value);
100ca987d46SWarner Losh #endif
101ca987d46SWarner Losh 
102ca987d46SWarner Losh 	return;
103ca987d46SWarner Losh }
104ca987d46SWarner Losh 
105ca987d46SWarner Losh void
106ca987d46SWarner Losh ficlSetenvq(FICL_VM *pVM)
107ca987d46SWarner Losh {
108ca987d46SWarner Losh #ifndef TESTMAIN
109ca987d46SWarner Losh 	char	*name, *value;
110ca987d46SWarner Losh #endif
111ca987d46SWarner Losh 	char	*namep, *valuep;
112ca987d46SWarner Losh 	int	names, values, overwrite;
113ca987d46SWarner Losh 
114ca987d46SWarner Losh #if FICL_ROBUST > 1
115ca987d46SWarner Losh 	vmCheckStack(pVM, 5, 0);
116ca987d46SWarner Losh #endif
117ca987d46SWarner Losh 	overwrite = stackPopINT(pVM->pStack);
118ca987d46SWarner Losh 	names = stackPopINT(pVM->pStack);
119ca987d46SWarner Losh 	namep = (char*) stackPopPtr(pVM->pStack);
120ca987d46SWarner Losh 	values = stackPopINT(pVM->pStack);
121ca987d46SWarner Losh 	valuep = (char*) stackPopPtr(pVM->pStack);
122ca987d46SWarner Losh 
123ca987d46SWarner Losh #ifndef TESTMAIN
124ca987d46SWarner Losh 	name = (char*) ficlMalloc(names+1);
125ca987d46SWarner Losh 	if (!name)
126ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
127ca987d46SWarner Losh 	strncpy(name, namep, names);
128ca987d46SWarner Losh 	name[names] = '\0';
129ca987d46SWarner Losh 	value = (char*) ficlMalloc(values+1);
130ca987d46SWarner Losh 	if (!value)
131ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
132ca987d46SWarner Losh 	strncpy(value, valuep, values);
133ca987d46SWarner Losh 	value[values] = '\0';
134ca987d46SWarner Losh 
135ca987d46SWarner Losh 	setenv(name, value, overwrite);
136ca987d46SWarner Losh 	ficlFree(name);
137ca987d46SWarner Losh 	ficlFree(value);
138ca987d46SWarner Losh #endif
139ca987d46SWarner Losh 
140ca987d46SWarner Losh 	return;
141ca987d46SWarner Losh }
142ca987d46SWarner Losh 
143ca987d46SWarner Losh void
144ca987d46SWarner Losh ficlGetenv(FICL_VM *pVM)
145ca987d46SWarner Losh {
146ca987d46SWarner Losh #ifndef TESTMAIN
147ca987d46SWarner Losh 	char	*name, *value;
148ca987d46SWarner Losh #endif
149ca987d46SWarner Losh 	char	*namep;
150ca987d46SWarner Losh 	int	names;
151ca987d46SWarner Losh 
152ca987d46SWarner Losh #if FICL_ROBUST > 1
153ca987d46SWarner Losh 	vmCheckStack(pVM, 2, 2);
154ca987d46SWarner Losh #endif
155ca987d46SWarner Losh 	names = stackPopINT(pVM->pStack);
156ca987d46SWarner Losh 	namep = (char*) stackPopPtr(pVM->pStack);
157ca987d46SWarner Losh 
158ca987d46SWarner Losh #ifndef TESTMAIN
159ca987d46SWarner Losh 	name = (char*) ficlMalloc(names+1);
160ca987d46SWarner Losh 	if (!name)
161ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
162ca987d46SWarner Losh 	strncpy(name, namep, names);
163ca987d46SWarner Losh 	name[names] = '\0';
164ca987d46SWarner Losh 
165ca987d46SWarner Losh 	value = getenv(name);
166ca987d46SWarner Losh 	ficlFree(name);
167ca987d46SWarner Losh 
168ca987d46SWarner Losh 	if(value != NULL) {
169ca987d46SWarner Losh 		stackPushPtr(pVM->pStack, value);
170ca987d46SWarner Losh 		stackPushINT(pVM->pStack, strlen(value));
171ca987d46SWarner Losh 	} else
172ca987d46SWarner Losh #endif
173ca987d46SWarner Losh 		stackPushINT(pVM->pStack, -1);
174ca987d46SWarner Losh 
175ca987d46SWarner Losh 	return;
176ca987d46SWarner Losh }
177ca987d46SWarner Losh 
178ca987d46SWarner Losh void
179ca987d46SWarner Losh ficlUnsetenv(FICL_VM *pVM)
180ca987d46SWarner Losh {
181ca987d46SWarner Losh #ifndef TESTMAIN
182ca987d46SWarner Losh 	char	*name;
183ca987d46SWarner Losh #endif
184ca987d46SWarner Losh 	char	*namep;
185ca987d46SWarner Losh 	int	names;
186ca987d46SWarner Losh 
187ca987d46SWarner Losh #if FICL_ROBUST > 1
188ca987d46SWarner Losh 	vmCheckStack(pVM, 2, 0);
189ca987d46SWarner Losh #endif
190ca987d46SWarner Losh 	names = stackPopINT(pVM->pStack);
191ca987d46SWarner Losh 	namep = (char*) stackPopPtr(pVM->pStack);
192ca987d46SWarner Losh 
193ca987d46SWarner Losh #ifndef TESTMAIN
194ca987d46SWarner Losh 	name = (char*) ficlMalloc(names+1);
195ca987d46SWarner Losh 	if (!name)
196ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
197ca987d46SWarner Losh 	strncpy(name, namep, names);
198ca987d46SWarner Losh 	name[names] = '\0';
199ca987d46SWarner Losh 
200ca987d46SWarner Losh 	unsetenv(name);
201ca987d46SWarner Losh 	ficlFree(name);
202ca987d46SWarner Losh #endif
203ca987d46SWarner Losh 
204ca987d46SWarner Losh 	return;
205ca987d46SWarner Losh }
206ca987d46SWarner Losh 
207ca987d46SWarner Losh void
208ca987d46SWarner Losh ficlCopyin(FICL_VM *pVM)
209ca987d46SWarner Losh {
210ca987d46SWarner Losh 	void*		src;
211ca987d46SWarner Losh 	vm_offset_t	dest;
212ca987d46SWarner Losh 	size_t		len;
213ca987d46SWarner Losh 
214ca987d46SWarner Losh #if FICL_ROBUST > 1
215ca987d46SWarner Losh 	vmCheckStack(pVM, 3, 0);
216ca987d46SWarner Losh #endif
217ca987d46SWarner Losh 
218ca987d46SWarner Losh 	len = stackPopINT(pVM->pStack);
219ca987d46SWarner Losh 	dest = stackPopINT(pVM->pStack);
220ca987d46SWarner Losh 	src = stackPopPtr(pVM->pStack);
221ca987d46SWarner Losh 
222ca987d46SWarner Losh #ifndef TESTMAIN
223ca987d46SWarner Losh 	archsw.arch_copyin(src, dest, len);
224ca987d46SWarner Losh #endif
225ca987d46SWarner Losh 
226ca987d46SWarner Losh 	return;
227ca987d46SWarner Losh }
228ca987d46SWarner Losh 
229ca987d46SWarner Losh void
230ca987d46SWarner Losh ficlCopyout(FICL_VM *pVM)
231ca987d46SWarner Losh {
232ca987d46SWarner Losh 	void*		dest;
233ca987d46SWarner Losh 	vm_offset_t	src;
234ca987d46SWarner Losh 	size_t		len;
235ca987d46SWarner Losh 
236ca987d46SWarner Losh #if FICL_ROBUST > 1
237ca987d46SWarner Losh 	vmCheckStack(pVM, 3, 0);
238ca987d46SWarner Losh #endif
239ca987d46SWarner Losh 
240ca987d46SWarner Losh 	len = stackPopINT(pVM->pStack);
241ca987d46SWarner Losh 	dest = stackPopPtr(pVM->pStack);
242ca987d46SWarner Losh 	src = stackPopINT(pVM->pStack);
243ca987d46SWarner Losh 
244ca987d46SWarner Losh #ifndef TESTMAIN
245ca987d46SWarner Losh 	archsw.arch_copyout(src, dest, len);
246ca987d46SWarner Losh #endif
247ca987d46SWarner Losh 
248ca987d46SWarner Losh 	return;
249ca987d46SWarner Losh }
250ca987d46SWarner Losh 
251ca987d46SWarner Losh void
252ca987d46SWarner Losh ficlFindfile(FICL_VM *pVM)
253ca987d46SWarner Losh {
254ca987d46SWarner Losh #ifndef TESTMAIN
255ca987d46SWarner Losh 	char	*name, *type;
256ca987d46SWarner Losh #endif
257ca987d46SWarner Losh 	char	*namep, *typep;
258ca987d46SWarner Losh 	struct	preloaded_file* fp;
259ca987d46SWarner Losh 	int	names, types;
260ca987d46SWarner Losh 
261ca987d46SWarner Losh #if FICL_ROBUST > 1
262ca987d46SWarner Losh 	vmCheckStack(pVM, 4, 1);
263ca987d46SWarner Losh #endif
264ca987d46SWarner Losh 
265ca987d46SWarner Losh 	types = stackPopINT(pVM->pStack);
266ca987d46SWarner Losh 	typep = (char*) stackPopPtr(pVM->pStack);
267ca987d46SWarner Losh 	names = stackPopINT(pVM->pStack);
268ca987d46SWarner Losh 	namep = (char*) stackPopPtr(pVM->pStack);
269ca987d46SWarner Losh #ifndef TESTMAIN
270ca987d46SWarner Losh 	name = (char*) ficlMalloc(names+1);
271ca987d46SWarner Losh 	if (!name)
272ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
273ca987d46SWarner Losh 	strncpy(name, namep, names);
274ca987d46SWarner Losh 	name[names] = '\0';
275ca987d46SWarner Losh 	type = (char*) ficlMalloc(types+1);
276ca987d46SWarner Losh 	if (!type)
277ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
278ca987d46SWarner Losh 	strncpy(type, typep, types);
279ca987d46SWarner Losh 	type[types] = '\0';
280ca987d46SWarner Losh 
281ca987d46SWarner Losh 	fp = file_findfile(name, type);
282ca987d46SWarner Losh #else
283ca987d46SWarner Losh 	fp = NULL;
284ca987d46SWarner Losh #endif
285ca987d46SWarner Losh 	stackPushPtr(pVM->pStack, fp);
286ca987d46SWarner Losh 
287ca987d46SWarner Losh 	return;
288ca987d46SWarner Losh }
289ca987d46SWarner Losh 
290e9b148a3SSimon J. Gerraty #ifndef TESTMAIN
291e9b148a3SSimon J. Gerraty 
292e9b148a3SSimon J. Gerraty /*	isvirtualized? - Return whether the loader runs under a
293e9b148a3SSimon J. Gerraty  *			hypervisor.
294e9b148a3SSimon J. Gerraty  *
295e9b148a3SSimon J. Gerraty  * isvirtualized? ( -- flag )
296e9b148a3SSimon J. Gerraty  */
297e9b148a3SSimon J. Gerraty static void
298e9b148a3SSimon J. Gerraty ficlIsvirtualizedQ(FICL_VM *pVM)
299e9b148a3SSimon J. Gerraty {
300e9b148a3SSimon J. Gerraty 	FICL_INT flag;
301e9b148a3SSimon J. Gerraty 	const char *hv;
302e9b148a3SSimon J. Gerraty 
303e9b148a3SSimon J. Gerraty #if FICL_ROBUST > 1
304e9b148a3SSimon J. Gerraty 	vmCheckStack(pVM, 0, 1);
305e9b148a3SSimon J. Gerraty #endif
306e9b148a3SSimon J. Gerraty 
307e9b148a3SSimon J. Gerraty 	hv = (archsw.arch_hypervisor != NULL)
308e9b148a3SSimon J. Gerraty 	    ? (*archsw.arch_hypervisor)()
309e9b148a3SSimon J. Gerraty 	    : NULL;
310e9b148a3SSimon J. Gerraty 	flag = (hv != NULL) ? FICL_TRUE : FICL_FALSE;
311e9b148a3SSimon J. Gerraty 	stackPushINT(pVM->pStack, flag);
312e9b148a3SSimon J. Gerraty }
313e9b148a3SSimon J. Gerraty 
314e9b148a3SSimon J. Gerraty #endif /* ndef TESTMAIN */
315e9b148a3SSimon J. Gerraty 
316ca987d46SWarner Losh void
317ca987d46SWarner Losh ficlCcall(FICL_VM *pVM)
318ca987d46SWarner Losh {
319ca987d46SWarner Losh 	int (*func)(int, ...);
320ca987d46SWarner Losh 	int result, p[10];
321ca987d46SWarner Losh 	int nparam, i;
322ca987d46SWarner Losh 
323ca987d46SWarner Losh #if FICL_ROBUST > 1
324ca987d46SWarner Losh 	vmCheckStack(pVM, 2, 0);
325ca987d46SWarner Losh #endif
326ca987d46SWarner Losh 
327ca987d46SWarner Losh 	func = stackPopPtr(pVM->pStack);
328ca987d46SWarner Losh 	nparam = stackPopINT(pVM->pStack);
329ca987d46SWarner Losh 
330ca987d46SWarner Losh #if FICL_ROBUST > 1
331ca987d46SWarner Losh 	vmCheckStack(pVM, nparam, 1);
332ca987d46SWarner Losh #endif
333ca987d46SWarner Losh 
334ca987d46SWarner Losh 	for (i = 0; i < nparam; i++)
335ca987d46SWarner Losh 		p[i] = stackPopINT(pVM->pStack);
336ca987d46SWarner Losh 
337ca987d46SWarner Losh 	result = func(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8],
338ca987d46SWarner Losh 	    p[9]);
339ca987d46SWarner Losh 
340ca987d46SWarner Losh 	stackPushINT(pVM->pStack, result);
341ca987d46SWarner Losh 
342ca987d46SWarner Losh 	return;
343ca987d46SWarner Losh }
344ca987d46SWarner Losh 
345ca987d46SWarner Losh void
346ca987d46SWarner Losh ficlUuidFromString(FICL_VM *pVM)
347ca987d46SWarner Losh {
348ca987d46SWarner Losh #ifndef	TESTMAIN
349ca987d46SWarner Losh 	char	*uuid;
350ca987d46SWarner Losh 	uint32_t status;
351ca987d46SWarner Losh #endif
352ca987d46SWarner Losh 	char	*uuidp;
353ca987d46SWarner Losh 	int	uuids;
354ca987d46SWarner Losh 	uuid_t	*u;
355ca987d46SWarner Losh 
356ca987d46SWarner Losh #if FICL_ROBUST > 1
357ca987d46SWarner Losh 	vmCheckStack(pVM, 2, 0);
358ca987d46SWarner Losh #endif
359ca987d46SWarner Losh 
360ca987d46SWarner Losh 	uuids = stackPopINT(pVM->pStack);
361ca987d46SWarner Losh 	uuidp = (char *) stackPopPtr(pVM->pStack);
362ca987d46SWarner Losh 
363ca987d46SWarner Losh #ifndef	TESTMAIN
364ca987d46SWarner Losh 	uuid = (char *)ficlMalloc(uuids + 1);
365ca987d46SWarner Losh 	if (!uuid)
366ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
367ca987d46SWarner Losh 	strncpy(uuid, uuidp, uuids);
368ca987d46SWarner Losh 	uuid[uuids] = '\0';
369ca987d46SWarner Losh 
370ca987d46SWarner Losh 	u = (uuid_t *)ficlMalloc(sizeof (*u));
371ca987d46SWarner Losh 
372ca987d46SWarner Losh 	uuid_from_string(uuid, u, &status);
373ca987d46SWarner Losh 	ficlFree(uuid);
374ca987d46SWarner Losh 	if (status != uuid_s_ok) {
375ca987d46SWarner Losh 		ficlFree(u);
376ca987d46SWarner Losh 		u = NULL;
377ca987d46SWarner Losh 	}
378ca987d46SWarner Losh #else
379ca987d46SWarner Losh 	u = NULL;
380ca987d46SWarner Losh #endif
381ca987d46SWarner Losh 	stackPushPtr(pVM->pStack, u);
382ca987d46SWarner Losh 
383ca987d46SWarner Losh 
384ca987d46SWarner Losh 	return;
385ca987d46SWarner Losh }
386ca987d46SWarner Losh 
387ca987d46SWarner Losh void
388ca987d46SWarner Losh ficlUuidToString(FICL_VM *pVM)
389ca987d46SWarner Losh {
390ca987d46SWarner Losh #ifndef	TESTMAIN
391ca987d46SWarner Losh 	char	*uuid;
392ca987d46SWarner Losh 	uint32_t status;
393ca987d46SWarner Losh #endif
394ca987d46SWarner Losh 	uuid_t	*u;
395ca987d46SWarner Losh 
396ca987d46SWarner Losh #if FICL_ROBUST > 1
397ca987d46SWarner Losh 	vmCheckStack(pVM, 1, 0);
398ca987d46SWarner Losh #endif
399ca987d46SWarner Losh 
400ca987d46SWarner Losh 	u = (uuid_t *)stackPopPtr(pVM->pStack);
401ca987d46SWarner Losh 
402ca987d46SWarner Losh #ifndef	TESTMAIN
403ca987d46SWarner Losh 	uuid_to_string(u, &uuid, &status);
404ca987d46SWarner Losh 	if (status != uuid_s_ok) {
405ca987d46SWarner Losh 		stackPushPtr(pVM->pStack, uuid);
406ca987d46SWarner Losh 		stackPushINT(pVM->pStack, strlen(uuid));
407ca987d46SWarner Losh 	} else
408ca987d46SWarner Losh #endif
409ca987d46SWarner Losh 		stackPushINT(pVM->pStack, -1);
410ca987d46SWarner Losh 
411ca987d46SWarner Losh 	return;
412ca987d46SWarner Losh }
413ca987d46SWarner Losh 
414ca987d46SWarner Losh /**************************************************************************
415ca987d46SWarner Losh                         f i c l E x e c F D
416ca987d46SWarner Losh ** reads in text from file fd and passes it to ficlExec()
417ca987d46SWarner Losh  * returns VM_OUTOFTEXT on success or the ficlExec() error code on
418ca987d46SWarner Losh  * failure.
419ca987d46SWarner Losh  */
420ca987d46SWarner Losh #define nLINEBUF 256
421ca987d46SWarner Losh int ficlExecFD(FICL_VM *pVM, int fd)
422ca987d46SWarner Losh {
423ca987d46SWarner Losh     char    cp[nLINEBUF];
424ca987d46SWarner Losh     int     nLine = 0, rval = VM_OUTOFTEXT;
425ca987d46SWarner Losh     char    ch;
426ca987d46SWarner Losh     CELL    id;
427ca987d46SWarner Losh 
428ca987d46SWarner Losh     id = pVM->sourceID;
429ca987d46SWarner Losh     pVM->sourceID.i = fd;
430ca987d46SWarner Losh 
431ca987d46SWarner Losh     /* feed each line to ficlExec */
432ca987d46SWarner Losh     while (1) {
433ca987d46SWarner Losh 	int status, i;
434ca987d46SWarner Losh 
435ca987d46SWarner Losh 	i = 0;
436ca987d46SWarner Losh 	while ((status = read(fd, &ch, 1)) > 0 && ch != '\n')
437ca987d46SWarner Losh 	    cp[i++] = ch;
438ca987d46SWarner Losh         nLine++;
439ca987d46SWarner Losh 	if (!i) {
440ca987d46SWarner Losh 	    if (status < 1)
441ca987d46SWarner Losh 		break;
442ca987d46SWarner Losh 	    continue;
443ca987d46SWarner Losh 	}
444ca987d46SWarner Losh         rval = ficlExecC(pVM, cp, i);
445ca987d46SWarner Losh 	if(rval != VM_QUIT && rval != VM_USEREXIT && rval != VM_OUTOFTEXT)
446ca987d46SWarner Losh         {
447ca987d46SWarner Losh             pVM->sourceID = id;
448ca987d46SWarner Losh             return rval;
449ca987d46SWarner Losh         }
450ca987d46SWarner Losh     }
451ca987d46SWarner Losh     /*
452ca987d46SWarner Losh     ** Pass an empty line with SOURCE-ID == -1 to flush
453ca987d46SWarner Losh     ** any pending REFILLs (as required by FILE wordset)
454ca987d46SWarner Losh     */
455ca987d46SWarner Losh     pVM->sourceID.i = -1;
456ca987d46SWarner Losh     ficlExec(pVM, "");
457ca987d46SWarner Losh 
458ca987d46SWarner Losh     pVM->sourceID = id;
459ca987d46SWarner Losh     return rval;
460ca987d46SWarner Losh }
461ca987d46SWarner Losh 
462ca987d46SWarner Losh static void displayCellNoPad(FICL_VM *pVM)
463ca987d46SWarner Losh {
464ca987d46SWarner Losh     CELL c;
465ca987d46SWarner Losh #if FICL_ROBUST > 1
466ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
467ca987d46SWarner Losh #endif
468ca987d46SWarner Losh     c = stackPop(pVM->pStack);
469ca987d46SWarner Losh     ltoa((c).i, pVM->pad, pVM->base);
470ca987d46SWarner Losh     vmTextOut(pVM, pVM->pad, 0);
471ca987d46SWarner Losh     return;
472ca987d46SWarner Losh }
473ca987d46SWarner Losh 
474ca987d46SWarner Losh /*      isdir? - Return whether an fd corresponds to a directory.
475ca987d46SWarner Losh  *
476ca987d46SWarner Losh  * isdir? ( fd -- bool )
477ca987d46SWarner Losh  */
478ca987d46SWarner Losh static void isdirQuestion(FICL_VM *pVM)
479ca987d46SWarner Losh {
480ca987d46SWarner Losh     struct stat sb;
481ca987d46SWarner Losh     FICL_INT flag;
482ca987d46SWarner Losh     int fd;
483ca987d46SWarner Losh 
484ca987d46SWarner Losh #if FICL_ROBUST > 1
485ca987d46SWarner Losh     vmCheckStack(pVM, 1, 1);
486ca987d46SWarner Losh #endif
487ca987d46SWarner Losh 
488ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack);
489ca987d46SWarner Losh     flag = FICL_FALSE;
490ca987d46SWarner Losh     do {
491ca987d46SWarner Losh         if (fd < 0)
492ca987d46SWarner Losh             break;
493ca987d46SWarner Losh         if (fstat(fd, &sb) < 0)
494ca987d46SWarner Losh             break;
495ca987d46SWarner Losh         if (!S_ISDIR(sb.st_mode))
496ca987d46SWarner Losh             break;
497ca987d46SWarner Losh         flag = FICL_TRUE;
498ca987d46SWarner Losh     } while (0);
499ca987d46SWarner Losh     stackPushINT(pVM->pStack, flag);
500ca987d46SWarner Losh }
501ca987d46SWarner Losh 
502ca987d46SWarner Losh /*          fopen - open a file and return new fd on stack.
503ca987d46SWarner Losh  *
504ca987d46SWarner Losh  * fopen ( ptr count mode -- fd )
505ca987d46SWarner Losh  */
506ca987d46SWarner Losh static void pfopen(FICL_VM *pVM)
507ca987d46SWarner Losh {
508ca987d46SWarner Losh     int     mode, fd, count;
509ca987d46SWarner Losh     char    *ptr, *name;
510ca987d46SWarner Losh 
511ca987d46SWarner Losh #if FICL_ROBUST > 1
512ca987d46SWarner Losh     vmCheckStack(pVM, 3, 1);
513ca987d46SWarner Losh #endif
514ca987d46SWarner Losh 
515ca987d46SWarner Losh     mode = stackPopINT(pVM->pStack);    /* get mode */
516ca987d46SWarner Losh     count = stackPopINT(pVM->pStack);   /* get count */
517ca987d46SWarner Losh     ptr = stackPopPtr(pVM->pStack);     /* get ptr */
518ca987d46SWarner Losh 
519ca987d46SWarner Losh     if ((count < 0) || (ptr == NULL)) {
520ca987d46SWarner Losh         stackPushINT(pVM->pStack, -1);
521ca987d46SWarner Losh         return;
522ca987d46SWarner Losh     }
523ca987d46SWarner Losh 
524ca987d46SWarner Losh     /* ensure that the string is null terminated */
525ca987d46SWarner Losh     name = (char *)malloc(count+1);
526ca987d46SWarner Losh     bcopy(ptr,name,count);
527ca987d46SWarner Losh     name[count] = 0;
528ca987d46SWarner Losh 
529ca987d46SWarner Losh     /* open the file */
530ca987d46SWarner Losh     fd = open(name, mode);
5312ef9ff7dSSimon J. Gerraty #ifdef LOADER_VERIEXEC
5322ef9ff7dSSimon J. Gerraty     if (fd >= 0) {
533*afc571b1SSimon J. Gerraty 	if (verify_file(fd, name, 0, VE_GUESS, __func__) < 0) {
5342ef9ff7dSSimon J. Gerraty 	    /* not verified writing ok but reading is not */
5352ef9ff7dSSimon J. Gerraty 	    if ((mode & O_ACCMODE) != O_WRONLY) {
5362ef9ff7dSSimon J. Gerraty 		close(fd);
5372ef9ff7dSSimon J. Gerraty 		fd = -1;
5382ef9ff7dSSimon J. Gerraty 	    }
5392ef9ff7dSSimon J. Gerraty 	} else {
5402ef9ff7dSSimon J. Gerraty 	    /* verified reading ok but writing is not */
5412ef9ff7dSSimon J. Gerraty 	    if ((mode & O_ACCMODE) != O_RDONLY) {
5422ef9ff7dSSimon J. Gerraty 		close(fd);
5432ef9ff7dSSimon J. Gerraty 		fd = -1;
5442ef9ff7dSSimon J. Gerraty 	    }
5452ef9ff7dSSimon J. Gerraty 	}
5462ef9ff7dSSimon J. Gerraty     }
5472ef9ff7dSSimon J. Gerraty #endif
548ca987d46SWarner Losh     free(name);
549ca987d46SWarner Losh     stackPushINT(pVM->pStack, fd);
550ca987d46SWarner Losh     return;
551ca987d46SWarner Losh }
552ca987d46SWarner Losh 
553ca987d46SWarner Losh /*          fclose - close a file who's fd is on stack.
554ca987d46SWarner Losh  *
555ca987d46SWarner Losh  * fclose ( fd -- )
556ca987d46SWarner Losh  */
557ca987d46SWarner Losh static void pfclose(FICL_VM *pVM)
558ca987d46SWarner Losh {
559ca987d46SWarner Losh     int fd;
560ca987d46SWarner Losh 
561ca987d46SWarner Losh #if FICL_ROBUST > 1
562ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
563ca987d46SWarner Losh #endif
564ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack); /* get fd */
565ca987d46SWarner Losh     if (fd != -1)
566ca987d46SWarner Losh 	close(fd);
567ca987d46SWarner Losh     return;
568ca987d46SWarner Losh }
569ca987d46SWarner Losh 
570ca987d46SWarner Losh /*          fread - read file contents
571ca987d46SWarner Losh  *
572ca987d46SWarner Losh  * fread  ( fd buf nbytes  -- nread )
573ca987d46SWarner Losh  */
574ca987d46SWarner Losh static void pfread(FICL_VM *pVM)
575ca987d46SWarner Losh {
576ca987d46SWarner Losh     int     fd, len;
577ca987d46SWarner Losh     char *buf;
578ca987d46SWarner Losh 
579ca987d46SWarner Losh #if FICL_ROBUST > 1
580ca987d46SWarner Losh     vmCheckStack(pVM, 3, 1);
581ca987d46SWarner Losh #endif
582ca987d46SWarner Losh     len = stackPopINT(pVM->pStack); /* get number of bytes to read */
583ca987d46SWarner Losh     buf = stackPopPtr(pVM->pStack); /* get buffer */
584ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack); /* get fd */
585ca987d46SWarner Losh     if (len > 0 && buf && fd != -1)
586ca987d46SWarner Losh 	stackPushINT(pVM->pStack, read(fd, buf, len));
587ca987d46SWarner Losh     else
588ca987d46SWarner Losh 	stackPushINT(pVM->pStack, -1);
589ca987d46SWarner Losh     return;
590ca987d46SWarner Losh }
591ca987d46SWarner Losh 
592ca987d46SWarner Losh /*      freaddir - read directory contents
593ca987d46SWarner Losh  *
594ca987d46SWarner Losh  * freaddir ( fd -- ptr len TRUE | FALSE )
595ca987d46SWarner Losh  */
596ca987d46SWarner Losh static void pfreaddir(FICL_VM *pVM)
597ca987d46SWarner Losh {
598ca987d46SWarner Losh #ifdef TESTMAIN
599ca987d46SWarner Losh     static struct dirent dirent;
600ca987d46SWarner Losh     struct stat sb;
601ca987d46SWarner Losh     char *buf;
602ca987d46SWarner Losh     off_t off, ptr;
603ca987d46SWarner Losh     u_int blksz;
604ca987d46SWarner Losh     int bufsz;
605ca987d46SWarner Losh #endif
606ca987d46SWarner Losh     struct dirent *d;
607ca987d46SWarner Losh     int fd;
608ca987d46SWarner Losh 
609ca987d46SWarner Losh #if FICL_ROBUST > 1
610ca987d46SWarner Losh     vmCheckStack(pVM, 1, 3);
611ca987d46SWarner Losh #endif
612ca987d46SWarner Losh 
613ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack);
614ca987d46SWarner Losh #if TESTMAIN
615ca987d46SWarner Losh     /*
616ca987d46SWarner Losh      * The readdirfd() function is specific to the loader environment.
617ca987d46SWarner Losh      * We do the best we can to make freaddir work, but it's not at
618ca987d46SWarner Losh      * all guaranteed.
619ca987d46SWarner Losh      */
620ca987d46SWarner Losh     d = NULL;
621ca987d46SWarner Losh     buf = NULL;
622ca987d46SWarner Losh     do {
623ca987d46SWarner Losh 	if (fd == -1)
624ca987d46SWarner Losh 	    break;
625ca987d46SWarner Losh 	if (fstat(fd, &sb) == -1)
626ca987d46SWarner Losh 	    break;
627ca987d46SWarner Losh 	blksz = (sb.st_blksize) ? sb.st_blksize : getpagesize();
628ca987d46SWarner Losh 	if ((blksz & (blksz - 1)) != 0)
629ca987d46SWarner Losh 	    break;
630ca987d46SWarner Losh 	buf = malloc(blksz);
631ca987d46SWarner Losh 	if (buf == NULL)
632ca987d46SWarner Losh 	    break;
633ca987d46SWarner Losh 	off = lseek(fd, 0LL, SEEK_CUR);
634ca987d46SWarner Losh 	if (off == -1)
635ca987d46SWarner Losh 	    break;
636ca987d46SWarner Losh 	ptr = off;
637ca987d46SWarner Losh 	if (lseek(fd, 0, SEEK_SET) == -1)
638ca987d46SWarner Losh 	    break;
639ca987d46SWarner Losh 	bufsz = getdents(fd, buf, blksz);
640ca987d46SWarner Losh 	while (bufsz > 0 && bufsz <= ptr) {
641ca987d46SWarner Losh 	    ptr -= bufsz;
642ca987d46SWarner Losh 	    bufsz = getdents(fd, buf, blksz);
643ca987d46SWarner Losh 	}
644ca987d46SWarner Losh 	if (bufsz <= 0)
645ca987d46SWarner Losh 	    break;
646ca987d46SWarner Losh 	d = (void *)(buf + ptr);
647ca987d46SWarner Losh 	dirent = *d;
648ca987d46SWarner Losh 	off += d->d_reclen;
649ca987d46SWarner Losh 	d = (lseek(fd, off, SEEK_SET) != off) ? NULL : &dirent;
650ca987d46SWarner Losh     } while (0);
651ca987d46SWarner Losh     if (buf != NULL)
652ca987d46SWarner Losh 	free(buf);
653ca987d46SWarner Losh #else
654ca987d46SWarner Losh     d = readdirfd(fd);
655ca987d46SWarner Losh #endif
656ca987d46SWarner Losh     if (d != NULL) {
657ca987d46SWarner Losh         stackPushPtr(pVM->pStack, d->d_name);
658ca987d46SWarner Losh         stackPushINT(pVM->pStack, strlen(d->d_name));
659ca987d46SWarner Losh         stackPushINT(pVM->pStack, FICL_TRUE);
660ca987d46SWarner Losh     } else {
661ca987d46SWarner Losh         stackPushINT(pVM->pStack, FICL_FALSE);
662ca987d46SWarner Losh     }
663ca987d46SWarner Losh }
664ca987d46SWarner Losh 
665ca987d46SWarner Losh /*          fload - interpret file contents
666ca987d46SWarner Losh  *
667ca987d46SWarner Losh  * fload  ( fd -- )
668ca987d46SWarner Losh  */
669ca987d46SWarner Losh static void pfload(FICL_VM *pVM)
670ca987d46SWarner Losh {
671ca987d46SWarner Losh     int     fd;
672ca987d46SWarner Losh 
673ca987d46SWarner Losh #if FICL_ROBUST > 1
674ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
675ca987d46SWarner Losh #endif
676ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack); /* get fd */
677ca987d46SWarner Losh     if (fd != -1)
678ca987d46SWarner Losh 	ficlExecFD(pVM, fd);
679ca987d46SWarner Losh     return;
680ca987d46SWarner Losh }
681ca987d46SWarner Losh 
682ca987d46SWarner Losh /*          fwrite - write file contents
683ca987d46SWarner Losh  *
684ca987d46SWarner Losh  * fwrite  ( fd buf nbytes  -- nwritten )
685ca987d46SWarner Losh  */
686ca987d46SWarner Losh static void pfwrite(FICL_VM *pVM)
687ca987d46SWarner Losh {
688ca987d46SWarner Losh     int     fd, len;
689ca987d46SWarner Losh     char *buf;
690ca987d46SWarner Losh 
691ca987d46SWarner Losh #if FICL_ROBUST > 1
692ca987d46SWarner Losh     vmCheckStack(pVM, 3, 1);
693ca987d46SWarner Losh #endif
694ca987d46SWarner Losh     len = stackPopINT(pVM->pStack); /* get number of bytes to read */
695ca987d46SWarner Losh     buf = stackPopPtr(pVM->pStack); /* get buffer */
696ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack); /* get fd */
697ca987d46SWarner Losh     if (len > 0 && buf && fd != -1)
698ca987d46SWarner Losh 	stackPushINT(pVM->pStack, write(fd, buf, len));
699ca987d46SWarner Losh     else
700ca987d46SWarner Losh 	stackPushINT(pVM->pStack, -1);
701ca987d46SWarner Losh     return;
702ca987d46SWarner Losh }
703ca987d46SWarner Losh 
704ca987d46SWarner Losh /*          fseek - seek to a new position in a file
705ca987d46SWarner Losh  *
706ca987d46SWarner Losh  * fseek  ( fd ofs whence  -- pos )
707ca987d46SWarner Losh  */
708ca987d46SWarner Losh static void pfseek(FICL_VM *pVM)
709ca987d46SWarner Losh {
710ca987d46SWarner Losh     int     fd, pos, whence;
711ca987d46SWarner Losh 
712ca987d46SWarner Losh #if FICL_ROBUST > 1
713ca987d46SWarner Losh     vmCheckStack(pVM, 3, 1);
714ca987d46SWarner Losh #endif
715ca987d46SWarner Losh     whence = stackPopINT(pVM->pStack);
716ca987d46SWarner Losh     pos = stackPopINT(pVM->pStack);
717ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack);
718ca987d46SWarner Losh     stackPushINT(pVM->pStack, lseek(fd, pos, whence));
719ca987d46SWarner Losh     return;
720ca987d46SWarner Losh }
721ca987d46SWarner Losh 
722ca987d46SWarner Losh /*           key - get a character from stdin
723ca987d46SWarner Losh  *
724ca987d46SWarner Losh  * key ( -- char )
725ca987d46SWarner Losh  */
726ca987d46SWarner Losh static void key(FICL_VM *pVM)
727ca987d46SWarner Losh {
728ca987d46SWarner Losh #if FICL_ROBUST > 1
729ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);
730ca987d46SWarner Losh #endif
731ca987d46SWarner Losh     stackPushINT(pVM->pStack, getchar());
732ca987d46SWarner Losh     return;
733ca987d46SWarner Losh }
734ca987d46SWarner Losh 
735ca987d46SWarner Losh /*           key? - check for a character from stdin (FACILITY)
736ca987d46SWarner Losh  *
737ca987d46SWarner Losh  * key? ( -- flag )
738ca987d46SWarner Losh  */
739ca987d46SWarner Losh static void keyQuestion(FICL_VM *pVM)
740ca987d46SWarner Losh {
741ca987d46SWarner Losh #if FICL_ROBUST > 1
742ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);
743ca987d46SWarner Losh #endif
744ca987d46SWarner Losh #ifdef TESTMAIN
745ca987d46SWarner Losh     /* XXX Since we don't fiddle with termios, let it always succeed... */
746ca987d46SWarner Losh     stackPushINT(pVM->pStack, FICL_TRUE);
747ca987d46SWarner Losh #else
748ca987d46SWarner Losh     /* But here do the right thing. */
749ca987d46SWarner Losh     stackPushINT(pVM->pStack, ischar()? FICL_TRUE : FICL_FALSE);
750ca987d46SWarner Losh #endif
751ca987d46SWarner Losh     return;
752ca987d46SWarner Losh }
753ca987d46SWarner Losh 
754ca987d46SWarner Losh /* seconds - gives number of seconds since beginning of time
755ca987d46SWarner Losh  *
756ca987d46SWarner Losh  * beginning of time is defined as:
757ca987d46SWarner Losh  *
758ca987d46SWarner Losh  *	BTX	- number of seconds since midnight
759ca987d46SWarner Losh  *	FreeBSD	- number of seconds since Jan 1 1970
760ca987d46SWarner Losh  *
761ca987d46SWarner Losh  * seconds ( -- u )
762ca987d46SWarner Losh  */
763ca987d46SWarner Losh static void pseconds(FICL_VM *pVM)
764ca987d46SWarner Losh {
765ca987d46SWarner Losh #if FICL_ROBUST > 1
766ca987d46SWarner Losh     vmCheckStack(pVM,0,1);
767ca987d46SWarner Losh #endif
768ca987d46SWarner Losh     stackPushUNS(pVM->pStack, (FICL_UNS) time(NULL));
769ca987d46SWarner Losh     return;
770ca987d46SWarner Losh }
771ca987d46SWarner Losh 
772ca987d46SWarner Losh /* ms - wait at least that many milliseconds (FACILITY)
773ca987d46SWarner Losh  *
774ca987d46SWarner Losh  * ms ( u -- )
775ca987d46SWarner Losh  *
776ca987d46SWarner Losh  */
777ca987d46SWarner Losh static void ms(FICL_VM *pVM)
778ca987d46SWarner Losh {
779ca987d46SWarner Losh #if FICL_ROBUST > 1
780ca987d46SWarner Losh     vmCheckStack(pVM,1,0);
781ca987d46SWarner Losh #endif
782ca987d46SWarner Losh #ifdef TESTMAIN
783ca987d46SWarner Losh     usleep(stackPopUNS(pVM->pStack)*1000);
784ca987d46SWarner Losh #else
785ca987d46SWarner Losh     delay(stackPopUNS(pVM->pStack)*1000);
786ca987d46SWarner Losh #endif
787ca987d46SWarner Losh     return;
788ca987d46SWarner Losh }
789ca987d46SWarner Losh 
790ca987d46SWarner Losh /*           fkey - get a character from a file
791ca987d46SWarner Losh  *
792ca987d46SWarner Losh  * fkey ( file -- char )
793ca987d46SWarner Losh  */
794ca987d46SWarner Losh static void fkey(FICL_VM *pVM)
795ca987d46SWarner Losh {
796ca987d46SWarner Losh     int i, fd;
797ca987d46SWarner Losh     char ch;
798ca987d46SWarner Losh 
799ca987d46SWarner Losh #if FICL_ROBUST > 1
800ca987d46SWarner Losh     vmCheckStack(pVM, 1, 1);
801ca987d46SWarner Losh #endif
802ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack);
803ca987d46SWarner Losh     i = read(fd, &ch, 1);
804ca987d46SWarner Losh     stackPushINT(pVM->pStack, i > 0 ? ch : -1);
805ca987d46SWarner Losh     return;
806ca987d46SWarner Losh }
807ca987d46SWarner Losh 
808ca987d46SWarner Losh 
809ca987d46SWarner Losh /*
810ca987d46SWarner Losh ** Retrieves free space remaining on the dictionary
811ca987d46SWarner Losh */
812ca987d46SWarner Losh 
813ca987d46SWarner Losh static void freeHeap(FICL_VM *pVM)
814ca987d46SWarner Losh {
815ca987d46SWarner Losh     stackPushINT(pVM->pStack, dictCellsAvail(ficlGetDict(pVM->pSys)));
816ca987d46SWarner Losh }
817ca987d46SWarner Losh 
818ca987d46SWarner Losh 
819ca987d46SWarner Losh /******************* Increase dictionary size on-demand ******************/
820ca987d46SWarner Losh 
821ca987d46SWarner Losh static void ficlDictThreshold(FICL_VM *pVM)
822ca987d46SWarner Losh {
823ca987d46SWarner Losh     stackPushPtr(pVM->pStack, &dictThreshold);
824ca987d46SWarner Losh }
825ca987d46SWarner Losh 
826ca987d46SWarner Losh static void ficlDictIncrease(FICL_VM *pVM)
827ca987d46SWarner Losh {
828ca987d46SWarner Losh     stackPushPtr(pVM->pStack, &dictIncrease);
829ca987d46SWarner Losh }
830ca987d46SWarner Losh 
831ca987d46SWarner Losh /**************************************************************************
832ca987d46SWarner Losh                         f i c l C o m p i l e P l a t f o r m
833ca987d46SWarner Losh ** Build FreeBSD platform extensions into the system dictionary
834ca987d46SWarner Losh **************************************************************************/
835ca987d46SWarner Losh void ficlCompilePlatform(FICL_SYSTEM *pSys)
836ca987d46SWarner Losh {
837ca987d46SWarner Losh     ficlCompileFcn **fnpp;
838ca987d46SWarner Losh     FICL_DICT *dp = pSys->dp;
839ca987d46SWarner Losh     assert (dp);
840ca987d46SWarner Losh 
841ca987d46SWarner Losh     dictAppendWord(dp, ".#",        displayCellNoPad,    FW_DEFAULT);
842ca987d46SWarner Losh     dictAppendWord(dp, "isdir?",    isdirQuestion,  FW_DEFAULT);
843ca987d46SWarner Losh     dictAppendWord(dp, "fopen",	    pfopen,	    FW_DEFAULT);
844ca987d46SWarner Losh     dictAppendWord(dp, "fclose",    pfclose,	    FW_DEFAULT);
845ca987d46SWarner Losh     dictAppendWord(dp, "fread",	    pfread,	    FW_DEFAULT);
846ca987d46SWarner Losh     dictAppendWord(dp, "freaddir",  pfreaddir,	    FW_DEFAULT);
847ca987d46SWarner Losh     dictAppendWord(dp, "fload",	    pfload,	    FW_DEFAULT);
848ca987d46SWarner Losh     dictAppendWord(dp, "fkey",	    fkey,	    FW_DEFAULT);
849ca987d46SWarner Losh     dictAppendWord(dp, "fseek",     pfseek,	    FW_DEFAULT);
850ca987d46SWarner Losh     dictAppendWord(dp, "fwrite",    pfwrite,	    FW_DEFAULT);
851ca987d46SWarner Losh     dictAppendWord(dp, "key",	    key,	    FW_DEFAULT);
852ca987d46SWarner Losh     dictAppendWord(dp, "key?",	    keyQuestion,    FW_DEFAULT);
853ca987d46SWarner Losh     dictAppendWord(dp, "ms",        ms,             FW_DEFAULT);
854ca987d46SWarner Losh     dictAppendWord(dp, "seconds",   pseconds,       FW_DEFAULT);
855ca987d46SWarner Losh     dictAppendWord(dp, "heap?",     freeHeap,       FW_DEFAULT);
856ca987d46SWarner Losh     dictAppendWord(dp, "dictthreshold", ficlDictThreshold, FW_DEFAULT);
857ca987d46SWarner Losh     dictAppendWord(dp, "dictincrease", ficlDictIncrease, FW_DEFAULT);
858ca987d46SWarner Losh 
859ca987d46SWarner Losh     dictAppendWord(dp, "setenv",    ficlSetenv,	    FW_DEFAULT);
860ca987d46SWarner Losh     dictAppendWord(dp, "setenv?",   ficlSetenvq,    FW_DEFAULT);
861ca987d46SWarner Losh     dictAppendWord(dp, "getenv",    ficlGetenv,	    FW_DEFAULT);
862ca987d46SWarner Losh     dictAppendWord(dp, "unsetenv",  ficlUnsetenv,   FW_DEFAULT);
863ca987d46SWarner Losh     dictAppendWord(dp, "copyin",    ficlCopyin,	    FW_DEFAULT);
864ca987d46SWarner Losh     dictAppendWord(dp, "copyout",   ficlCopyout,    FW_DEFAULT);
865ca987d46SWarner Losh     dictAppendWord(dp, "findfile",  ficlFindfile,   FW_DEFAULT);
866ca987d46SWarner Losh     dictAppendWord(dp, "ccall",	    ficlCcall,	    FW_DEFAULT);
867ca987d46SWarner Losh     dictAppendWord(dp, "uuid-from-string", ficlUuidFromString, FW_DEFAULT);
868ca987d46SWarner Losh     dictAppendWord(dp, "uuid-to-string", ficlUuidToString, FW_DEFAULT);
869e9b148a3SSimon J. Gerraty #ifndef TESTMAIN
870e9b148a3SSimon J. Gerraty     dictAppendWord(dp, "isvirtualized?",ficlIsvirtualizedQ, FW_DEFAULT);
871e9b148a3SSimon J. Gerraty #endif
872ca987d46SWarner Losh 
873ca987d46SWarner Losh     SET_FOREACH(fnpp, Xficl_compile_set)
874ca987d46SWarner Losh 	(*fnpp)(pSys);
875ca987d46SWarner Losh 
876ca987d46SWarner Losh #if defined(__i386__)
877ca987d46SWarner Losh     ficlSetEnv(pSys, "arch-i386",         FICL_TRUE);
878ca987d46SWarner Losh     ficlSetEnv(pSys, "arch-powerpc",      FICL_FALSE);
879ca987d46SWarner Losh #elif defined(__powerpc__)
880ca987d46SWarner Losh     ficlSetEnv(pSys, "arch-i386",         FICL_FALSE);
881ca987d46SWarner Losh     ficlSetEnv(pSys, "arch-powerpc",      FICL_TRUE);
882ca987d46SWarner Losh #endif
883ca987d46SWarner Losh 
884ca987d46SWarner Losh     return;
885ca987d46SWarner Losh }
886