1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2000-2003 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29/*
30 * Embedded Fcode Interpreter
31 *
32 * Process cmd line args and invoke Fcode engine.
33 */
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <sys/wait.h>
37#include <fcntl.h>
38#include <unistd.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <strings.h>
42#include <stropts.h>
43#include <ctype.h>
44
45#include <fcode/engine.h>
46#include <fcode/log.h>
47#include <fcode/debug.h>
48
49#include <fcdriver/fcdriver.h>
50
51#define	MSG_ERRLOG_DEFAULT	(MSG_FATAL|MSG_ERROR|MSG_WARN|MSG_INFO|\
52				    MSG_DEBUG|MSG_FC_DEBUG)
53#define	MSG_SYSLOG_DEFAULT	(MSG_FATAL|MSG_ERROR|MSG_WARN)
54#define	DEBUG_FC_LIST		(DEBUG_COMMA|DEBUG_EXEC_TRACE|\
55				    DEBUG_EXEC_DUMP_RS|DEBUG_EXEC_DUMP_RS|\
56				    DEBUG_EXEC_SHOW_VITALS|DEBUG_TRACING|\
57				    DEBUG_BYTELOAD_DS|DEBUG_BYTELOAD_RS|\
58				    DEBUG_BYTELOAD_TOKENS|DEBUG_SHOW_RS|\
59				    DEBUG_SHOW_STACK)
60
61common_data_t common;
62
63void *fc_env;
64
65void
66usage(char *argv[])
67{
68	log_message(MSG_ERROR, "Usage: %s <flags>\n", argv[0]);
69	log_message(MSG_ERROR,
70	    "    -D                        fcode_debug = true\n");
71	log_message(MSG_ERROR,
72	    "    -d <level>                set debug level\n");
73	log_message(MSG_ERROR,
74	    "    -f <file>                 interpret fcode/source <file>\n");
75	log_message(MSG_ERROR,
76	    "    -i                        go 'interactive'\n");
77	log_message(MSG_ERROR,
78	    "    -s <string>               interpret <string> as forth\n");
79	log_message(MSG_ERROR,
80	    "    -a                        FCODE image has a.out header\n");
81	log_message(MSG_ERROR,
82	    "    -e [<msglvl>:]<errorlog>  Set error log file\n");
83	log_message(MSG_ERROR,
84	    "    -l <msglvl>               Set syslog message level\n");
85	log_message(MSG_ERROR,
86	    "    -k                        Toggle OBP page kludge\n");
87}
88
89fcode_env_t *env;
90
91int
92main(int argc, char *argv[])
93{
94	extern char *optarg;
95	extern int optind, opterr, optopt;
96	int c, aout = 0;
97	char *fcode_file = NULL;
98	char *forthstr = NULL;
99	int debug = 0;
100	int syslog_flags = MSG_SYSLOG_DEFAULT;
101	int lflag = 0;
102	int error_log_flags;
103	char *errlog = NULL;
104	extern void run_one_efdaemon_request(fcode_env_t *);
105
106	common.Progname = argv[0];
107	common.search_path = getenv("FC_SEARCH_PATH");
108	common.fcode_fd = -1;
109	env = fc_env  = clone_environment(NULL, &common);
110
111	while ((c = getopt(argc, argv, "ad:e:f:l:iDs:k")) != EOF) {
112		switch (c) {
113		case 'a':
114			aout = 1;
115			break;
116
117		case 'd':
118			debug = debug_flags_to_mask(optarg);
119			set_interpreter_debug_level(debug);
120			if (debug)
121				env->fcode_debug = 1;
122			break;
123
124		case 'e':
125			if ((errlog = strchr(optarg, ':')) != NULL) {
126				*errlog++ = '\0';
127				error_log_flags = parse_msg_flags(optarg);
128			} else {
129				errlog = optarg;
130				error_log_flags = MSG_ERRLOG_DEFAULT;
131			}
132			open_error_log(errlog, error_log_flags);
133			break;
134
135		case 'l':
136			syslog_flags = parse_msg_flags(optarg);
137			lflag++;
138			break;
139
140		case 'D':
141			env->fcode_debug = 1;
142			break;
143
144		case 'f':
145			fcode_file = optarg;
146			break;
147
148		case 'i':
149			forthstr = "interact";
150			env->fcode_debug = 1;
151			break;
152
153		case 's':
154			forthstr = optarg;
155			break;
156
157		case '?':
158			usage(argv);
159			exit(1);
160		}
161	}
162
163	if (forthstr) {
164		run_fcode(env, (uchar_t *)forthstr, strlen(forthstr));
165	} else if (fcode_file) {
166		run_fcode_from_file(env, fcode_file, aout);
167	} else {
168		if ((debug & DEBUG_FC_LIST) != 0 &&
169		    ((error_log_flags | syslog_flags) & MSG_FC_DEBUG) == 0) {
170			log_message(MSG_WARN, "Warning, verbose debug flag(s)"
171			    " on, but syslog/errlog not enabled for verbose"
172			    " debug\n");
173			if (errlog)
174				error_log_flags |= MSG_FC_DEBUG;
175			else
176				syslog_flags |= MSG_FC_DEBUG;
177		}
178		if ((debug & ~DEBUG_FC_LIST) != 0 &&
179		    ((error_log_flags | syslog_flags) & MSG_DEBUG) == 0) {
180			log_message(MSG_WARN, "Warning, debug flag(s) on, but"
181			    " syslog/errlog not enabled for debug\n");
182			if (errlog)
183				error_log_flags |= MSG_DEBUG;
184			else
185				syslog_flags |= MSG_DEBUG;
186		}
187
188		if (errlog == NULL || lflag) {
189			if (syslog_flags & MSG_FC_DEBUG)
190				log_message(MSG_WARN, "Warning, verbose debug"
191				    " not recommended for syslog\n");
192			open_syslog_log("interpreter", syslog_flags);
193		}
194		run_one_efdaemon_request(env);
195	}
196
197	return (0);
198}
199