10a4f1df1SToomas Soome /*
2199767f8SToomas Soome * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3199767f8SToomas Soome * All rights reserved.
4199767f8SToomas Soome *
5199767f8SToomas Soome * Redistribution and use in source and binary forms, with or without
6199767f8SToomas Soome * modification, are permitted provided that the following conditions
7199767f8SToomas Soome * are met:
8199767f8SToomas Soome * 1. Redistributions of source code must retain the above copyright
9199767f8SToomas Soome * notice, this list of conditions and the following disclaimer.
10199767f8SToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
11199767f8SToomas Soome * notice, this list of conditions and the following disclaimer in the
12199767f8SToomas Soome * documentation and/or other materials provided with the distribution.
13199767f8SToomas Soome *
14199767f8SToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15199767f8SToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16199767f8SToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17199767f8SToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18199767f8SToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19199767f8SToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20199767f8SToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21199767f8SToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22199767f8SToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23199767f8SToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24199767f8SToomas Soome * SUCH DAMAGE.
25199767f8SToomas Soome */
26199767f8SToomas Soome
27199767f8SToomas Soome #include <sys/cdefs.h>
28199767f8SToomas Soome
29199767f8SToomas Soome #include <stand.h>
30199767f8SToomas Soome #include <string.h>
31199767f8SToomas Soome
32199767f8SToomas Soome #include "bootstrap.h"
33199767f8SToomas Soome
34199767f8SToomas Soome const char *command_errmsg;
35199767f8SToomas Soome /* XXX should have procedural interface for setting, size limit? */
36199767f8SToomas Soome char command_errbuf[COMMAND_ERRBUFSZ];
37199767f8SToomas Soome
38199767f8SToomas Soome static int page_file(char *filename);
39199767f8SToomas Soome
40e4768a34SToomas Soome /* BEGIN CSTYLED */
41199767f8SToomas Soome /*
42199767f8SToomas Soome * Help is read from a formatted text file.
43199767f8SToomas Soome *
44e4768a34SToomas Soome * Entries in the file are formatted as
45199767f8SToomas Soome
46199767f8SToomas Soome # Ttopic [Ssubtopic] Ddescription
47199767f8SToomas Soome help
48199767f8SToomas Soome text
49199767f8SToomas Soome here
50199767f8SToomas Soome #
51199767f8SToomas Soome
52199767f8SToomas Soome *
53199767f8SToomas Soome * Note that for code simplicity's sake, the above format must be followed
54199767f8SToomas Soome * exactly.
55199767f8SToomas Soome *
56199767f8SToomas Soome * Subtopic entries must immediately follow the topic (this is used to
57199767f8SToomas Soome * produce the listing of subtopics).
58199767f8SToomas Soome *
59199767f8SToomas Soome * If no argument(s) are supplied by the user, the help for 'help' is displayed.
60199767f8SToomas Soome */
61e4768a34SToomas Soome /* END CSTYLED */
62199767f8SToomas Soome COMMAND_SET(help, "help", "detailed help", command_help);
63199767f8SToomas Soome
64199767f8SToomas Soome static int
help_getnext(int fd,char ** topic,char ** subtopic,char ** desc)65e4768a34SToomas Soome help_getnext(int fd, char **topic, char **subtopic, char **desc)
66199767f8SToomas Soome {
67e4768a34SToomas Soome char line[81], *cp, *ep;
68e4768a34SToomas Soome
69e4768a34SToomas Soome /* Make sure we provide sane values. */
70e4768a34SToomas Soome *topic = *subtopic = *desc = NULL;
71e4768a34SToomas Soome for (;;) {
72e4768a34SToomas Soome if (fgetstr(line, 80, fd) < 0)
73e4768a34SToomas Soome return (0);
74e4768a34SToomas Soome
75e4768a34SToomas Soome if (strlen(line) < 3 || line[0] != '#' || line[1] != ' ')
76e4768a34SToomas Soome continue;
77e4768a34SToomas Soome
78e4768a34SToomas Soome *topic = *subtopic = *desc = NULL;
79e4768a34SToomas Soome cp = line + 2;
80e4768a34SToomas Soome while (cp != NULL && *cp != 0) {
81e4768a34SToomas Soome ep = strchr(cp, ' ');
82e4768a34SToomas Soome if (*cp == 'T' && *topic == NULL) {
83e4768a34SToomas Soome if (ep != NULL)
84e4768a34SToomas Soome *ep++ = 0;
85e4768a34SToomas Soome *topic = strdup(cp + 1);
86e4768a34SToomas Soome } else if (*cp == 'S' && *subtopic == NULL) {
87e4768a34SToomas Soome if (ep != NULL)
88e4768a34SToomas Soome *ep++ = 0;
89e4768a34SToomas Soome *subtopic = strdup(cp + 1);
90e4768a34SToomas Soome } else if (*cp == 'D') {
91e4768a34SToomas Soome *desc = strdup(cp + 1);
92e4768a34SToomas Soome ep = NULL;
93e4768a34SToomas Soome }
94e4768a34SToomas Soome cp = ep;
95e4768a34SToomas Soome }
96e4768a34SToomas Soome if (*topic == NULL) {
97e4768a34SToomas Soome free(*subtopic);
98e4768a34SToomas Soome free(*desc);
99e4768a34SToomas Soome *subtopic = *desc = NULL;
100e4768a34SToomas Soome continue;
101e4768a34SToomas Soome }
102e4768a34SToomas Soome return (1);
103199767f8SToomas Soome }
104199767f8SToomas Soome }
105199767f8SToomas Soome
106199767f8SToomas Soome static int
help_emitsummary(char * topic,char * subtopic,char * desc)107199767f8SToomas Soome help_emitsummary(char *topic, char *subtopic, char *desc)
108199767f8SToomas Soome {
109e4768a34SToomas Soome int i;
110e4768a34SToomas Soome
111e4768a34SToomas Soome pager_output(" ");
112e4768a34SToomas Soome pager_output(topic);
113e4768a34SToomas Soome i = strlen(topic);
114e4768a34SToomas Soome if (subtopic != NULL) {
115e4768a34SToomas Soome pager_output(" ");
116e4768a34SToomas Soome pager_output(subtopic);
117e4768a34SToomas Soome i += strlen(subtopic) + 1;
118e4768a34SToomas Soome }
119e4768a34SToomas Soome if (desc != NULL) {
120e4768a34SToomas Soome do {
121e4768a34SToomas Soome pager_output(" ");
122e4768a34SToomas Soome } while (i++ < 30);
123e4768a34SToomas Soome pager_output(desc);
124e4768a34SToomas Soome }
125e4768a34SToomas Soome return (pager_output("\n"));
126199767f8SToomas Soome }
127199767f8SToomas Soome
128e4768a34SToomas Soome
129199767f8SToomas Soome static int
command_help(int argc,char * argv[])130e4768a34SToomas Soome command_help(int argc, char *argv[])
131199767f8SToomas Soome {
132e4768a34SToomas Soome char buf[81]; /* XXX buffer size? */
133e4768a34SToomas Soome int hfd, matched, doindex;
134e4768a34SToomas Soome char *topic, *subtopic, *t, *s, *d;
135e4768a34SToomas Soome
136e4768a34SToomas Soome /* page the help text from our load path */
137e4768a34SToomas Soome snprintf(buf, sizeof (buf), "%s/boot/loader.help", getenv("loaddev"));
138e4768a34SToomas Soome if ((hfd = open(buf, O_RDONLY)) < 0) {
139e4768a34SToomas Soome printf("Verbose help not available, "
140e4768a34SToomas Soome "use '?' to list commands\n");
141e4768a34SToomas Soome return (CMD_OK);
142e4768a34SToomas Soome }
143199767f8SToomas Soome
144e4768a34SToomas Soome /* pick up request from arguments */
145e4768a34SToomas Soome topic = subtopic = NULL;
146e4768a34SToomas Soome switch (argc) {
147e4768a34SToomas Soome case 3:
148e4768a34SToomas Soome subtopic = strdup(argv[2]);
149e4768a34SToomas Soome /* FALLTHROUGH */
150e4768a34SToomas Soome case 2:
151e4768a34SToomas Soome topic = strdup(argv[1]);
152e4768a34SToomas Soome break;
153e4768a34SToomas Soome case 1:
154e4768a34SToomas Soome topic = strdup("help");
155199767f8SToomas Soome break;
156e4768a34SToomas Soome default:
157e4768a34SToomas Soome command_errmsg = "usage is 'help <topic> [<subtopic>]";
158e4768a34SToomas Soome close(hfd);
159e4768a34SToomas Soome return (CMD_ERROR);
160e4768a34SToomas Soome }
161199767f8SToomas Soome
162e4768a34SToomas Soome /* magic "index" keyword */
163e4768a34SToomas Soome doindex = strcmp(topic, "index") == 0? 1 : 0;
164e4768a34SToomas Soome matched = doindex;
165e4768a34SToomas Soome
166e4768a34SToomas Soome /* Scan the helpfile looking for help matching the request */
167e4768a34SToomas Soome pager_open();
168e4768a34SToomas Soome while (help_getnext(hfd, &t, &s, &d)) {
169e4768a34SToomas Soome
170e4768a34SToomas Soome if (doindex) { /* dink around formatting */
171e4768a34SToomas Soome if (help_emitsummary(t, s, d))
172e4768a34SToomas Soome break;
173e4768a34SToomas Soome
174e4768a34SToomas Soome } else if (strcmp(topic, t)) {
175e4768a34SToomas Soome /* topic mismatch */
176e4768a34SToomas Soome if (matched) {
177e4768a34SToomas Soome /* nothing more on this topic, stop scanning */
178e4768a34SToomas Soome break;
179e4768a34SToomas Soome }
180e4768a34SToomas Soome } else {
181e4768a34SToomas Soome /* topic matched */
182e4768a34SToomas Soome matched = 1;
183e4768a34SToomas Soome if ((subtopic == NULL && s == NULL) ||
184e4768a34SToomas Soome (subtopic != NULL && s != NULL &&
185e4768a34SToomas Soome strcmp(subtopic, s) == 0)) {
186e4768a34SToomas Soome /* exact match, print text */
187e4768a34SToomas Soome while (fgetstr(buf, 80, hfd) >= 0 &&
188e4768a34SToomas Soome buf[0] != '#') {
189e4768a34SToomas Soome if (pager_output(buf))
190e4768a34SToomas Soome break;
191e4768a34SToomas Soome if (pager_output("\n"))
192e4768a34SToomas Soome break;
193e4768a34SToomas Soome }
194e4768a34SToomas Soome } else if (subtopic == NULL && s != NULL) {
195e4768a34SToomas Soome /* topic match, list subtopics */
196e4768a34SToomas Soome if (help_emitsummary(t, s, d))
197e4768a34SToomas Soome break;
198e4768a34SToomas Soome }
199199767f8SToomas Soome }
200e4768a34SToomas Soome free(t);
201e4768a34SToomas Soome free(s);
202e4768a34SToomas Soome free(d);
203e4768a34SToomas Soome t = s = d = NULL;
204199767f8SToomas Soome }
205199767f8SToomas Soome free(t);
206199767f8SToomas Soome free(s);
207199767f8SToomas Soome free(d);
208e4768a34SToomas Soome pager_close();
209e4768a34SToomas Soome close(hfd);
210e4768a34SToomas Soome if (!matched) {
211e4768a34SToomas Soome snprintf(command_errbuf, sizeof (command_errbuf),
212e4768a34SToomas Soome "no help available for '%s'", topic);
213e4768a34SToomas Soome free(topic);
214e4768a34SToomas Soome free(subtopic);
215e4768a34SToomas Soome return (CMD_ERROR);
216e4768a34SToomas Soome }
217199767f8SToomas Soome free(topic);
2180a4f1df1SToomas Soome free(subtopic);
219e4768a34SToomas Soome return (CMD_OK);
220199767f8SToomas Soome }
221199767f8SToomas Soome
222199767f8SToomas Soome COMMAND_SET(commandlist, "?", "list commands", command_commandlist);
223199767f8SToomas Soome
224199767f8SToomas Soome static int
command_commandlist(int argc __unused,char * argv[]__unused)2250a4f1df1SToomas Soome command_commandlist(int argc __unused, char *argv[] __unused)
226199767f8SToomas Soome {
227e4768a34SToomas Soome struct bootblk_command **cmdp;
228e4768a34SToomas Soome int res;
229e4768a34SToomas Soome char name[20];
230e4768a34SToomas Soome
231e4768a34SToomas Soome res = 0;
232e4768a34SToomas Soome pager_open();
233e4768a34SToomas Soome res = pager_output("Available commands:\n");
234e4768a34SToomas Soome SET_FOREACH(cmdp, Xcommand_set) {
235e4768a34SToomas Soome if (res)
236e4768a34SToomas Soome break;
237e4768a34SToomas Soome if ((*cmdp)->c_name != NULL && (*cmdp)->c_desc != NULL) {
238e4768a34SToomas Soome snprintf(name, sizeof (name)," %-15s ",
239e4768a34SToomas Soome (*cmdp)->c_name);
240e4768a34SToomas Soome pager_output(name);
241e4768a34SToomas Soome pager_output((*cmdp)->c_desc);
242e4768a34SToomas Soome res = pager_output("\n");
243e4768a34SToomas Soome }
244199767f8SToomas Soome }
245e4768a34SToomas Soome pager_close();
246e4768a34SToomas Soome return (CMD_OK);
247199767f8SToomas Soome }
248199767f8SToomas Soome
249199767f8SToomas Soome /*
250199767f8SToomas Soome * XXX set/show should become set/echo if we have variable
251199767f8SToomas Soome * substitution happening.
252199767f8SToomas Soome */
253199767f8SToomas Soome
254199767f8SToomas Soome COMMAND_SET(show, "show", "show variable(s)", command_show);
255199767f8SToomas Soome
256199767f8SToomas Soome static int
command_show(int argc,char * argv[])257199767f8SToomas Soome command_show(int argc, char *argv[])
258199767f8SToomas Soome {
259e4768a34SToomas Soome struct env_var *ev;
260e4768a34SToomas Soome char *cp;
261e4768a34SToomas Soome
262e4768a34SToomas Soome if (argc < 2) {
263e4768a34SToomas Soome /*
264e4768a34SToomas Soome * With no arguments, print everything.
265e4768a34SToomas Soome */
266e4768a34SToomas Soome pager_open();
267e4768a34SToomas Soome for (ev = environ; ev != NULL; ev = ev->ev_next) {
268e4768a34SToomas Soome pager_output(ev->ev_name);
269e4768a34SToomas Soome cp = getenv(ev->ev_name);
270e4768a34SToomas Soome if (cp != NULL) {
271e4768a34SToomas Soome pager_output("=");
272e4768a34SToomas Soome pager_output(cp);
273e4768a34SToomas Soome }
274e4768a34SToomas Soome if (pager_output("\n"))
275e4768a34SToomas Soome break;
276e4768a34SToomas Soome }
277e4768a34SToomas Soome pager_close();
278199767f8SToomas Soome } else {
279e4768a34SToomas Soome if ((cp = getenv(argv[1])) != NULL) {
280e4768a34SToomas Soome printf("%s\n", cp);
281e4768a34SToomas Soome } else {
282e4768a34SToomas Soome snprintf(command_errbuf, sizeof (command_errbuf),
283e4768a34SToomas Soome "variable '%s' not found", argv[1]);
284e4768a34SToomas Soome return (CMD_ERROR);
285e4768a34SToomas Soome }
286199767f8SToomas Soome }
287e4768a34SToomas Soome return (CMD_OK);
288199767f8SToomas Soome }
289199767f8SToomas Soome
290199767f8SToomas Soome COMMAND_SET(set, "set", "set a variable", command_set);
291199767f8SToomas Soome
292199767f8SToomas Soome static int
command_set(int argc,char * argv[])293199767f8SToomas Soome command_set(int argc, char *argv[])
294199767f8SToomas Soome {
295e4768a34SToomas Soome int err;
296e4768a34SToomas Soome
297e4768a34SToomas Soome if (argc != 2) {
298e4768a34SToomas Soome command_errmsg = "wrong number of arguments";
299e4768a34SToomas Soome return (CMD_ERROR);
300e4768a34SToomas Soome } else {
301e4768a34SToomas Soome if ((err = putenv(argv[1])) != 0) {
302e4768a34SToomas Soome command_errmsg = strerror(err);
303e4768a34SToomas Soome return (CMD_ERROR);
304e4768a34SToomas Soome }
305199767f8SToomas Soome }
306e4768a34SToomas Soome return (CMD_OK);
307199767f8SToomas Soome }
308199767f8SToomas Soome
309199767f8SToomas Soome COMMAND_SET(setprop, "setprop", "set a variable", command_setprop);
310199767f8SToomas Soome
311199767f8SToomas Soome static int
command_setprop(int argc,char * argv[])312199767f8SToomas Soome command_setprop(int argc, char *argv[])
313199767f8SToomas Soome {
314e4768a34SToomas Soome int err;
315e4768a34SToomas Soome
316e4768a34SToomas Soome if (argc != 3) {
317e4768a34SToomas Soome command_errmsg = "wrong number of arguments";
318e4768a34SToomas Soome return (CMD_ERROR);
319e4768a34SToomas Soome } else {
320e4768a34SToomas Soome if ((err = setenv(argv[1], argv[2], 1)) != 0) {
321e4768a34SToomas Soome command_errmsg = strerror(err);
322e4768a34SToomas Soome return (CMD_ERROR);
323e4768a34SToomas Soome }
324199767f8SToomas Soome }
325e4768a34SToomas Soome return (CMD_OK);
326199767f8SToomas Soome }
327199767f8SToomas Soome
328199767f8SToomas Soome COMMAND_SET(unset, "unset", "unset a variable", command_unset);
329199767f8SToomas Soome
330199767f8SToomas Soome static int
command_unset(int argc,char * argv[])331e4768a34SToomas Soome command_unset(int argc, char *argv[])
332199767f8SToomas Soome {
333e4768a34SToomas Soome int err;
334e4768a34SToomas Soome
335e4768a34SToomas Soome if (argc != 2) {
336e4768a34SToomas Soome command_errmsg = "wrong number of arguments";
337e4768a34SToomas Soome return (CMD_ERROR);
338e4768a34SToomas Soome } else {
339e4768a34SToomas Soome if ((err = unsetenv(argv[1])) != 0) {
340e4768a34SToomas Soome command_errmsg = strerror(err);
341e4768a34SToomas Soome return (CMD_ERROR);
342e4768a34SToomas Soome }
343199767f8SToomas Soome }
344e4768a34SToomas Soome return (CMD_OK);
345199767f8SToomas Soome }
346199767f8SToomas Soome
347199767f8SToomas Soome COMMAND_SET(echo, "echo", "echo arguments", command_echo);
348199767f8SToomas Soome
349199767f8SToomas Soome static int
command_echo(int argc,char * argv[])350199767f8SToomas Soome command_echo(int argc, char *argv[])
351199767f8SToomas Soome {
352e4768a34SToomas Soome char *s;
353e4768a34SToomas Soome int nl, ch;
354e4768a34SToomas Soome
355e4768a34SToomas Soome nl = 0;
356e4768a34SToomas Soome optind = 1;
357e4768a34SToomas Soome optreset = 1;
358e4768a34SToomas Soome while ((ch = getopt(argc, argv, "n")) != -1) {
359e4768a34SToomas Soome switch (ch) {
360e4768a34SToomas Soome case 'n':
361e4768a34SToomas Soome nl = 1;
362e4768a34SToomas Soome break;
363e4768a34SToomas Soome case '?':
364e4768a34SToomas Soome default:
365e4768a34SToomas Soome /* getopt has already reported an error */
366e4768a34SToomas Soome return (CMD_OK);
367e4768a34SToomas Soome }
368199767f8SToomas Soome }
369e4768a34SToomas Soome argv += (optind);
370e4768a34SToomas Soome argc -= (optind);
371199767f8SToomas Soome
372e4768a34SToomas Soome s = unargv(argc, argv);
373e4768a34SToomas Soome if (s != NULL) {
374e4768a34SToomas Soome printf("%s", s);
375e4768a34SToomas Soome free(s);
376e4768a34SToomas Soome }
377e4768a34SToomas Soome if (!nl)
378e4768a34SToomas Soome printf("\n");
379e4768a34SToomas Soome return (CMD_OK);
380199767f8SToomas Soome }
381199767f8SToomas Soome
382199767f8SToomas Soome /*
383199767f8SToomas Soome * A passable emulation of the sh(1) command of the same name.
384199767f8SToomas Soome */
385199767f8SToomas Soome
386199767f8SToomas Soome COMMAND_SET(read, "read", "read input from the terminal", command_read);
387199767f8SToomas Soome
388199767f8SToomas Soome static int
command_read(int argc,char * argv[])389199767f8SToomas Soome command_read(int argc, char *argv[])
390199767f8SToomas Soome {
391e4768a34SToomas Soome char *prompt;
392e4768a34SToomas Soome int timeout;
393e4768a34SToomas Soome time_t when;
394e4768a34SToomas Soome char *cp;
395e4768a34SToomas Soome char *name;
396e4768a34SToomas Soome char buf[256]; /* XXX size? */
397e4768a34SToomas Soome int c;
398e4768a34SToomas Soome
399e4768a34SToomas Soome timeout = -1;
400e4768a34SToomas Soome prompt = NULL;
401e4768a34SToomas Soome optind = 1;
402e4768a34SToomas Soome optreset = 1;
403e4768a34SToomas Soome while ((c = getopt(argc, argv, "p:t:")) != -1) {
404e4768a34SToomas Soome switch (c) {
405e4768a34SToomas Soome case 'p':
406e4768a34SToomas Soome prompt = optarg;
407e4768a34SToomas Soome break;
408e4768a34SToomas Soome case 't':
409e4768a34SToomas Soome timeout = strtol(optarg, &cp, 0);
410e4768a34SToomas Soome if (cp == optarg) {
411e4768a34SToomas Soome snprintf(command_errbuf,
412e4768a34SToomas Soome sizeof (command_errbuf),
413e4768a34SToomas Soome "bad timeout '%s'", optarg);
414e4768a34SToomas Soome return (CMD_ERROR);
415e4768a34SToomas Soome }
416e4768a34SToomas Soome break;
417e4768a34SToomas Soome default:
418e4768a34SToomas Soome return (CMD_OK);
419e4768a34SToomas Soome }
420199767f8SToomas Soome }
421e4768a34SToomas Soome
422e4768a34SToomas Soome argv += (optind);
423e4768a34SToomas Soome argc -= (optind);
424e4768a34SToomas Soome name = (argc > 0) ? argv[0]: NULL;
425e4768a34SToomas Soome
426e4768a34SToomas Soome if (prompt != NULL)
427e4768a34SToomas Soome printf("%s", prompt);
428e4768a34SToomas Soome if (timeout >= 0) {
429e4768a34SToomas Soome when = time(NULL) + timeout;
430e4768a34SToomas Soome while (!ischar())
431e4768a34SToomas Soome if (time(NULL) >= when)
432e4768a34SToomas Soome return (CMD_OK); /* is timeout an error? */
433e4768a34SToomas Soome }
434e4768a34SToomas Soome
435e4768a34SToomas Soome ngets(buf, sizeof (buf));
436e4768a34SToomas Soome
437e4768a34SToomas Soome if (name != NULL)
438e4768a34SToomas Soome setenv(name, buf, 1);
439e4768a34SToomas Soome return (CMD_OK);
440199767f8SToomas Soome }
441199767f8SToomas Soome
442199767f8SToomas Soome /*
443199767f8SToomas Soome * File pager
444199767f8SToomas Soome */
445199767f8SToomas Soome COMMAND_SET(more, "more", "show contents of a file", command_more);
446199767f8SToomas Soome
447199767f8SToomas Soome static int
command_more(int argc,char * argv[])448199767f8SToomas Soome command_more(int argc, char *argv[])
449199767f8SToomas Soome {
450e4768a34SToomas Soome int i;
451e4768a34SToomas Soome int res;
452e4768a34SToomas Soome char line[80];
453e4768a34SToomas Soome
454e4768a34SToomas Soome res = 0;
455e4768a34SToomas Soome pager_open();
456e4768a34SToomas Soome for (i = 1; (i < argc) && (res == 0); i++) {
457e4768a34SToomas Soome snprintf(line, sizeof (line), "*** FILE %s BEGIN ***\n",
458e4768a34SToomas Soome argv[i]);
459e4768a34SToomas Soome if (pager_output(line))
460e4768a34SToomas Soome break;
461e4768a34SToomas Soome res = page_file(argv[i]);
462e4768a34SToomas Soome if (!res) {
463e4768a34SToomas Soome snprintf(line, sizeof (line), "*** FILE %s END ***\n",
464e4768a34SToomas Soome argv[i]);
465e4768a34SToomas Soome res = pager_output(line);
466e4768a34SToomas Soome }
467199767f8SToomas Soome }
468e4768a34SToomas Soome pager_close();
469199767f8SToomas Soome
470e4768a34SToomas Soome if (res == 0)
471e4768a34SToomas Soome return (CMD_OK);
472e4768a34SToomas Soome else
473e4768a34SToomas Soome return (CMD_ERROR);
474199767f8SToomas Soome }
475199767f8SToomas Soome
476199767f8SToomas Soome static int
page_file(char * filename)477199767f8SToomas Soome page_file(char *filename)
478199767f8SToomas Soome {
479e4768a34SToomas Soome int result;
480199767f8SToomas Soome
481e4768a34SToomas Soome result = pager_file(filename);
482199767f8SToomas Soome
483e4768a34SToomas Soome if (result == -1) {
484e4768a34SToomas Soome snprintf(command_errbuf, sizeof (command_errbuf),
485e4768a34SToomas Soome "error showing %s", filename);
486e4768a34SToomas Soome }
487199767f8SToomas Soome
488e4768a34SToomas Soome return (result);
489e4768a34SToomas Soome }
490199767f8SToomas Soome
491199767f8SToomas Soome /*
492199767f8SToomas Soome * List all disk-like devices
493199767f8SToomas Soome */
494199767f8SToomas Soome COMMAND_SET(lsdev, "lsdev", "list all devices", command_lsdev);
495199767f8SToomas Soome
496199767f8SToomas Soome static int
command_lsdev(int argc,char * argv[])497199767f8SToomas Soome command_lsdev(int argc, char *argv[])
498199767f8SToomas Soome {
499e4768a34SToomas Soome int verbose, ch, i;
500e4768a34SToomas Soome char line[80];
501e4768a34SToomas Soome
502e4768a34SToomas Soome verbose = 0;
503e4768a34SToomas Soome optind = 1;
504e4768a34SToomas Soome optreset = 1;
505e4768a34SToomas Soome while ((ch = getopt(argc, argv, "v")) != -1) {
506e4768a34SToomas Soome switch (ch) {
507e4768a34SToomas Soome case 'v':
508e4768a34SToomas Soome verbose = 1;
509e4768a34SToomas Soome break;
510e4768a34SToomas Soome case '?':
511e4768a34SToomas Soome default:
512e4768a34SToomas Soome /* getopt has already reported an error */
513e4768a34SToomas Soome return (CMD_OK);
514e4768a34SToomas Soome }
515199767f8SToomas Soome }
516e4768a34SToomas Soome argv += (optind);
517e4768a34SToomas Soome argc -= (optind);
518e4768a34SToomas Soome
519e4768a34SToomas Soome pager_open();
520e4768a34SToomas Soome for (i = 0; devsw[i] != NULL; i++) {
521e4768a34SToomas Soome if (devsw[i]->dv_print != NULL) {
522e4768a34SToomas Soome if (devsw[i]->dv_print(verbose))
523e4768a34SToomas Soome break;
524e4768a34SToomas Soome } else {
525e4768a34SToomas Soome snprintf(line, sizeof (line), "%s: (unknown)\n",
526e4768a34SToomas Soome devsw[i]->dv_name);
527e4768a34SToomas Soome if (pager_output(line))
528e4768a34SToomas Soome break;
529e4768a34SToomas Soome }
530199767f8SToomas Soome }
531e4768a34SToomas Soome pager_close();
532e4768a34SToomas Soome return (CMD_OK);
533199767f8SToomas Soome }
534