1*22028508SToomas Soome /*
2*22028508SToomas Soome * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3*22028508SToomas Soome * All rights reserved.
4*22028508SToomas Soome *
5*22028508SToomas Soome * Redistribution and use in source and binary forms, with or without
6*22028508SToomas Soome * modification, are permitted provided that the following conditions
7*22028508SToomas Soome * are met:
8*22028508SToomas Soome * 1. Redistributions of source code must retain the above copyright
9*22028508SToomas Soome * notice, this list of conditions and the following disclaimer.
10*22028508SToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
11*22028508SToomas Soome * notice, this list of conditions and the following disclaimer in the
12*22028508SToomas Soome * documentation and/or other materials provided with the distribution.
13*22028508SToomas Soome *
14*22028508SToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*22028508SToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*22028508SToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*22028508SToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*22028508SToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*22028508SToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*22028508SToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*22028508SToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*22028508SToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*22028508SToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*22028508SToomas Soome * SUCH DAMAGE.
25*22028508SToomas Soome */
26*22028508SToomas Soome
27*22028508SToomas Soome #include <sys/cdefs.h>
28*22028508SToomas Soome
29*22028508SToomas Soome #include <stand.h>
30*22028508SToomas Soome #include <string.h>
31*22028508SToomas Soome
32*22028508SToomas Soome #include "bootstrap.h"
33*22028508SToomas Soome
34*22028508SToomas Soome const char *command_errmsg;
35*22028508SToomas Soome /* XXX should have procedural interface for setting, size limit? */
36*22028508SToomas Soome char command_errbuf[COMMAND_ERRBUFSZ];
37*22028508SToomas Soome
38*22028508SToomas Soome static int page_file(char *filename);
39*22028508SToomas Soome
40*22028508SToomas Soome /* BEGIN CSTYLED */
41*22028508SToomas Soome /*
42*22028508SToomas Soome * Help is read from a formatted text file.
43*22028508SToomas Soome *
44*22028508SToomas Soome * Entries in the file are formatted as
45*22028508SToomas Soome
46*22028508SToomas Soome # Ttopic [Ssubtopic] Ddescription
47*22028508SToomas Soome help
48*22028508SToomas Soome text
49*22028508SToomas Soome here
50*22028508SToomas Soome #
51*22028508SToomas Soome
52*22028508SToomas Soome *
53*22028508SToomas Soome * Note that for code simplicity's sake, the above format must be followed
54*22028508SToomas Soome * exactly.
55*22028508SToomas Soome *
56*22028508SToomas Soome * Subtopic entries must immediately follow the topic (this is used to
57*22028508SToomas Soome * produce the listing of subtopics).
58*22028508SToomas Soome *
59*22028508SToomas Soome * If no argument(s) are supplied by the user, the help for 'help' is displayed.
60*22028508SToomas Soome */
61*22028508SToomas Soome /* END CSTYLED */
62*22028508SToomas Soome COMMAND_SET(help, "help", "detailed help", command_help);
63*22028508SToomas Soome
64*22028508SToomas Soome static int
help_getnext(int fd,char ** topic,char ** subtopic,char ** desc)65*22028508SToomas Soome help_getnext(int fd, char **topic, char **subtopic, char **desc)
66*22028508SToomas Soome {
67*22028508SToomas Soome char line[81], *cp, *ep;
68*22028508SToomas Soome
69*22028508SToomas Soome /* Make sure we provide sane values. */
70*22028508SToomas Soome *topic = *subtopic = *desc = NULL;
71*22028508SToomas Soome for (;;) {
72*22028508SToomas Soome if (fgetstr(line, 80, fd) < 0)
73*22028508SToomas Soome return (0);
74*22028508SToomas Soome
75*22028508SToomas Soome if (strlen(line) < 3 || line[0] != '#' || line[1] != ' ')
76*22028508SToomas Soome continue;
77*22028508SToomas Soome
78*22028508SToomas Soome *topic = *subtopic = *desc = NULL;
79*22028508SToomas Soome cp = line + 2;
80*22028508SToomas Soome while (cp != NULL && *cp != 0) {
81*22028508SToomas Soome ep = strchr(cp, ' ');
82*22028508SToomas Soome if (*cp == 'T' && *topic == NULL) {
83*22028508SToomas Soome if (ep != NULL)
84*22028508SToomas Soome *ep++ = 0;
85*22028508SToomas Soome *topic = strdup(cp + 1);
86*22028508SToomas Soome } else if (*cp == 'S' && *subtopic == NULL) {
87*22028508SToomas Soome if (ep != NULL)
88*22028508SToomas Soome *ep++ = 0;
89*22028508SToomas Soome *subtopic = strdup(cp + 1);
90*22028508SToomas Soome } else if (*cp == 'D') {
91*22028508SToomas Soome *desc = strdup(cp + 1);
92*22028508SToomas Soome ep = NULL;
93*22028508SToomas Soome }
94*22028508SToomas Soome cp = ep;
95*22028508SToomas Soome }
96*22028508SToomas Soome if (*topic == NULL) {
97*22028508SToomas Soome free(*subtopic);
98*22028508SToomas Soome free(*desc);
99*22028508SToomas Soome *subtopic = *desc = NULL;
100*22028508SToomas Soome continue;
101*22028508SToomas Soome }
102*22028508SToomas Soome return (1);
103*22028508SToomas Soome }
104*22028508SToomas Soome }
105*22028508SToomas Soome
106*22028508SToomas Soome static int
help_emitsummary(char * topic,char * subtopic,char * desc)107*22028508SToomas Soome help_emitsummary(char *topic, char *subtopic, char *desc)
108*22028508SToomas Soome {
109*22028508SToomas Soome int i;
110*22028508SToomas Soome
111*22028508SToomas Soome pager_output(" ");
112*22028508SToomas Soome pager_output(topic);
113*22028508SToomas Soome i = strlen(topic);
114*22028508SToomas Soome if (subtopic != NULL) {
115*22028508SToomas Soome pager_output(" ");
116*22028508SToomas Soome pager_output(subtopic);
117*22028508SToomas Soome i += strlen(subtopic) + 1;
118*22028508SToomas Soome }
119*22028508SToomas Soome if (desc != NULL) {
120*22028508SToomas Soome do {
121*22028508SToomas Soome pager_output(" ");
122*22028508SToomas Soome } while (i++ < 30);
123*22028508SToomas Soome pager_output(desc);
124*22028508SToomas Soome }
125*22028508SToomas Soome return (pager_output("\n"));
126*22028508SToomas Soome }
127*22028508SToomas Soome
128*22028508SToomas Soome
129*22028508SToomas Soome static int
command_help(int argc,char * argv[])130*22028508SToomas Soome command_help(int argc, char *argv[])
131*22028508SToomas Soome {
132*22028508SToomas Soome char buf[81]; /* XXX buffer size? */
133*22028508SToomas Soome int hfd, matched, doindex;
134*22028508SToomas Soome char *topic, *subtopic, *t, *s, *d;
135*22028508SToomas Soome
136*22028508SToomas Soome /* page the help text from our load path */
137*22028508SToomas Soome snprintf(buf, sizeof (buf), "%s/boot/loader.help", getenv("loaddev"));
138*22028508SToomas Soome if ((hfd = open(buf, O_RDONLY)) < 0) {
139*22028508SToomas Soome printf("Verbose help not available, "
140*22028508SToomas Soome "use '?' to list commands\n");
141*22028508SToomas Soome return (CMD_OK);
142*22028508SToomas Soome }
143*22028508SToomas Soome
144*22028508SToomas Soome /* pick up request from arguments */
145*22028508SToomas Soome topic = subtopic = NULL;
146*22028508SToomas Soome switch (argc) {
147*22028508SToomas Soome case 3:
148*22028508SToomas Soome subtopic = strdup(argv[2]);
149*22028508SToomas Soome /* FALLTHROUGH */
150*22028508SToomas Soome case 2:
151*22028508SToomas Soome topic = strdup(argv[1]);
152*22028508SToomas Soome break;
153*22028508SToomas Soome case 1:
154*22028508SToomas Soome topic = strdup("help");
155*22028508SToomas Soome break;
156*22028508SToomas Soome default:
157*22028508SToomas Soome command_errmsg = "usage is 'help <topic> [<subtopic>]";
158*22028508SToomas Soome close(hfd);
159*22028508SToomas Soome return (CMD_ERROR);
160*22028508SToomas Soome }
161*22028508SToomas Soome
162*22028508SToomas Soome /* magic "index" keyword */
163*22028508SToomas Soome doindex = strcmp(topic, "index") == 0? 1 : 0;
164*22028508SToomas Soome matched = doindex;
165*22028508SToomas Soome
166*22028508SToomas Soome /* Scan the helpfile looking for help matching the request */
167*22028508SToomas Soome pager_open();
168*22028508SToomas Soome while (help_getnext(hfd, &t, &s, &d)) {
169*22028508SToomas Soome
170*22028508SToomas Soome if (doindex) { /* dink around formatting */
171*22028508SToomas Soome if (help_emitsummary(t, s, d))
172*22028508SToomas Soome break;
173*22028508SToomas Soome
174*22028508SToomas Soome } else if (strcmp(topic, t)) {
175*22028508SToomas Soome /* topic mismatch */
176*22028508SToomas Soome if (matched) {
177*22028508SToomas Soome /* nothing more on this topic, stop scanning */
178*22028508SToomas Soome break;
179*22028508SToomas Soome }
180*22028508SToomas Soome } else {
181*22028508SToomas Soome /* topic matched */
182*22028508SToomas Soome matched = 1;
183*22028508SToomas Soome if ((subtopic == NULL && s == NULL) ||
184*22028508SToomas Soome (subtopic != NULL && s != NULL &&
185*22028508SToomas Soome strcmp(subtopic, s) == 0)) {
186*22028508SToomas Soome /* exact match, print text */
187*22028508SToomas Soome while (fgetstr(buf, 80, hfd) >= 0 &&
188*22028508SToomas Soome buf[0] != '#') {
189*22028508SToomas Soome if (pager_output(buf))
190*22028508SToomas Soome break;
191*22028508SToomas Soome if (pager_output("\n"))
192*22028508SToomas Soome break;
193*22028508SToomas Soome }
194*22028508SToomas Soome } else if (subtopic == NULL && s != NULL) {
195*22028508SToomas Soome /* topic match, list subtopics */
196*22028508SToomas Soome if (help_emitsummary(t, s, d))
197*22028508SToomas Soome break;
198*22028508SToomas Soome }
199*22028508SToomas Soome }
200*22028508SToomas Soome free(t);
201*22028508SToomas Soome free(s);
202*22028508SToomas Soome free(d);
203*22028508SToomas Soome t = s = d = NULL;
204*22028508SToomas Soome }
205*22028508SToomas Soome free(t);
206*22028508SToomas Soome free(s);
207*22028508SToomas Soome free(d);
208*22028508SToomas Soome pager_close();
209*22028508SToomas Soome close(hfd);
210*22028508SToomas Soome if (!matched) {
211*22028508SToomas Soome snprintf(command_errbuf, sizeof (command_errbuf),
212*22028508SToomas Soome "no help available for '%s'", topic);
213*22028508SToomas Soome free(topic);
214*22028508SToomas Soome free(subtopic);
215*22028508SToomas Soome return (CMD_ERROR);
216*22028508SToomas Soome }
217*22028508SToomas Soome free(topic);
218*22028508SToomas Soome free(subtopic);
219*22028508SToomas Soome return (CMD_OK);
220*22028508SToomas Soome }
221*22028508SToomas Soome
222*22028508SToomas Soome COMMAND_SET(commandlist, "?", "list commands", command_commandlist);
223*22028508SToomas Soome
224*22028508SToomas Soome static int
command_commandlist(int argc __unused,char * argv[]__unused)225*22028508SToomas Soome command_commandlist(int argc __unused, char *argv[] __unused)
226*22028508SToomas Soome {
227*22028508SToomas Soome struct bootblk_command **cmdp;
228*22028508SToomas Soome int res;
229*22028508SToomas Soome char name[20];
230*22028508SToomas Soome
231*22028508SToomas Soome res = 0;
232*22028508SToomas Soome pager_open();
233*22028508SToomas Soome res = pager_output("Available commands:\n");
234*22028508SToomas Soome SET_FOREACH(cmdp, Xcommand_set) {
235*22028508SToomas Soome if (res)
236*22028508SToomas Soome break;
237*22028508SToomas Soome if ((*cmdp)->c_name != NULL && (*cmdp)->c_desc != NULL) {
238*22028508SToomas Soome snprintf(name, sizeof (name)," %-15s ",
239*22028508SToomas Soome (*cmdp)->c_name);
240*22028508SToomas Soome pager_output(name);
241*22028508SToomas Soome pager_output((*cmdp)->c_desc);
242*22028508SToomas Soome res = pager_output("\n");
243*22028508SToomas Soome }
244*22028508SToomas Soome }
245*22028508SToomas Soome pager_close();
246*22028508SToomas Soome return (CMD_OK);
247*22028508SToomas Soome }
248*22028508SToomas Soome
249*22028508SToomas Soome /*
250*22028508SToomas Soome * XXX set/show should become set/echo if we have variable
251*22028508SToomas Soome * substitution happening.
252*22028508SToomas Soome */
253*22028508SToomas Soome
254*22028508SToomas Soome COMMAND_SET(show, "show", "show variable(s)", command_show);
255*22028508SToomas Soome
256*22028508SToomas Soome static int
command_show(int argc,char * argv[])257*22028508SToomas Soome command_show(int argc, char *argv[])
258*22028508SToomas Soome {
259*22028508SToomas Soome struct env_var *ev;
260*22028508SToomas Soome char *cp;
261*22028508SToomas Soome
262*22028508SToomas Soome if (argc < 2) {
263*22028508SToomas Soome /*
264*22028508SToomas Soome * With no arguments, print everything.
265*22028508SToomas Soome */
266*22028508SToomas Soome pager_open();
267*22028508SToomas Soome for (ev = environ; ev != NULL; ev = ev->ev_next) {
268*22028508SToomas Soome pager_output(ev->ev_name);
269*22028508SToomas Soome cp = getenv(ev->ev_name);
270*22028508SToomas Soome if (cp != NULL) {
271*22028508SToomas Soome pager_output("=");
272*22028508SToomas Soome pager_output(cp);
273*22028508SToomas Soome }
274*22028508SToomas Soome if (pager_output("\n"))
275*22028508SToomas Soome break;
276*22028508SToomas Soome }
277*22028508SToomas Soome pager_close();
278*22028508SToomas Soome } else {
279*22028508SToomas Soome if ((cp = getenv(argv[1])) != NULL) {
280*22028508SToomas Soome printf("%s\n", cp);
281*22028508SToomas Soome } else {
282*22028508SToomas Soome snprintf(command_errbuf, sizeof (command_errbuf),
283*22028508SToomas Soome "variable '%s' not found", argv[1]);
284*22028508SToomas Soome return (CMD_ERROR);
285*22028508SToomas Soome }
286*22028508SToomas Soome }
287*22028508SToomas Soome return (CMD_OK);
288*22028508SToomas Soome }
289*22028508SToomas Soome
290*22028508SToomas Soome COMMAND_SET(set, "set", "set a variable", command_set);
291*22028508SToomas Soome
292*22028508SToomas Soome static int
command_set(int argc,char * argv[])293*22028508SToomas Soome command_set(int argc, char *argv[])
294*22028508SToomas Soome {
295*22028508SToomas Soome int err;
296*22028508SToomas Soome
297*22028508SToomas Soome if (argc != 2) {
298*22028508SToomas Soome command_errmsg = "wrong number of arguments";
299*22028508SToomas Soome return (CMD_ERROR);
300*22028508SToomas Soome } else {
301*22028508SToomas Soome if ((err = putenv(argv[1])) != 0) {
302*22028508SToomas Soome command_errmsg = strerror(err);
303*22028508SToomas Soome return (CMD_ERROR);
304*22028508SToomas Soome }
305*22028508SToomas Soome }
306*22028508SToomas Soome return (CMD_OK);
307*22028508SToomas Soome }
308*22028508SToomas Soome
309*22028508SToomas Soome COMMAND_SET(setprop, "setprop", "set a variable", command_setprop);
310*22028508SToomas Soome
311*22028508SToomas Soome static int
command_setprop(int argc,char * argv[])312*22028508SToomas Soome command_setprop(int argc, char *argv[])
313*22028508SToomas Soome {
314*22028508SToomas Soome int err;
315*22028508SToomas Soome
316*22028508SToomas Soome if (argc != 3) {
317*22028508SToomas Soome command_errmsg = "wrong number of arguments";
318*22028508SToomas Soome return (CMD_ERROR);
319*22028508SToomas Soome } else {
320*22028508SToomas Soome if ((err = setenv(argv[1], argv[2], 1)) != 0) {
321*22028508SToomas Soome command_errmsg = strerror(err);
322*22028508SToomas Soome return (CMD_ERROR);
323*22028508SToomas Soome }
324*22028508SToomas Soome }
325*22028508SToomas Soome return (CMD_OK);
326*22028508SToomas Soome }
327*22028508SToomas Soome
328*22028508SToomas Soome COMMAND_SET(unset, "unset", "unset a variable", command_unset);
329*22028508SToomas Soome
330*22028508SToomas Soome static int
command_unset(int argc,char * argv[])331*22028508SToomas Soome command_unset(int argc, char *argv[])
332*22028508SToomas Soome {
333*22028508SToomas Soome int err;
334*22028508SToomas Soome
335*22028508SToomas Soome if (argc != 2) {
336*22028508SToomas Soome command_errmsg = "wrong number of arguments";
337*22028508SToomas Soome return (CMD_ERROR);
338*22028508SToomas Soome } else {
339*22028508SToomas Soome if ((err = unsetenv(argv[1])) != 0) {
340*22028508SToomas Soome command_errmsg = strerror(err);
341*22028508SToomas Soome return (CMD_ERROR);
342*22028508SToomas Soome }
343*22028508SToomas Soome }
344*22028508SToomas Soome return (CMD_OK);
345*22028508SToomas Soome }
346*22028508SToomas Soome
347*22028508SToomas Soome COMMAND_SET(echo, "echo", "echo arguments", command_echo);
348*22028508SToomas Soome
349*22028508SToomas Soome static int
command_echo(int argc,char * argv[])350*22028508SToomas Soome command_echo(int argc, char *argv[])
351*22028508SToomas Soome {
352*22028508SToomas Soome char *s;
353*22028508SToomas Soome int nl, ch;
354*22028508SToomas Soome
355*22028508SToomas Soome nl = 0;
356*22028508SToomas Soome optind = 1;
357*22028508SToomas Soome optreset = 1;
358*22028508SToomas Soome while ((ch = getopt(argc, argv, "n")) != -1) {
359*22028508SToomas Soome switch (ch) {
360*22028508SToomas Soome case 'n':
361*22028508SToomas Soome nl = 1;
362*22028508SToomas Soome break;
363*22028508SToomas Soome case '?':
364*22028508SToomas Soome default:
365*22028508SToomas Soome /* getopt has already reported an error */
366*22028508SToomas Soome return (CMD_OK);
367*22028508SToomas Soome }
368*22028508SToomas Soome }
369*22028508SToomas Soome argv += (optind);
370*22028508SToomas Soome argc -= (optind);
371*22028508SToomas Soome
372*22028508SToomas Soome s = unargv(argc, argv);
373*22028508SToomas Soome if (s != NULL) {
374*22028508SToomas Soome printf("%s", s);
375*22028508SToomas Soome free(s);
376*22028508SToomas Soome }
377*22028508SToomas Soome if (!nl)
378*22028508SToomas Soome printf("\n");
379*22028508SToomas Soome return (CMD_OK);
380*22028508SToomas Soome }
381*22028508SToomas Soome
382*22028508SToomas Soome /*
383*22028508SToomas Soome * A passable emulation of the sh(1) command of the same name.
384*22028508SToomas Soome */
385*22028508SToomas Soome
386*22028508SToomas Soome COMMAND_SET(read, "read", "read input from the terminal", command_read);
387*22028508SToomas Soome
388*22028508SToomas Soome static int
command_read(int argc,char * argv[])389*22028508SToomas Soome command_read(int argc, char *argv[])
390*22028508SToomas Soome {
391*22028508SToomas Soome char *prompt;
392*22028508SToomas Soome int timeout;
393*22028508SToomas Soome time_t when;
394*22028508SToomas Soome char *cp;
395*22028508SToomas Soome char *name;
396*22028508SToomas Soome char buf[256]; /* XXX size? */
397*22028508SToomas Soome int c;
398*22028508SToomas Soome
399*22028508SToomas Soome timeout = -1;
400*22028508SToomas Soome prompt = NULL;
401*22028508SToomas Soome optind = 1;
402*22028508SToomas Soome optreset = 1;
403*22028508SToomas Soome while ((c = getopt(argc, argv, "p:t:")) != -1) {
404*22028508SToomas Soome switch (c) {
405*22028508SToomas Soome case 'p':
406*22028508SToomas Soome prompt = optarg;
407*22028508SToomas Soome break;
408*22028508SToomas Soome case 't':
409*22028508SToomas Soome timeout = strtol(optarg, &cp, 0);
410*22028508SToomas Soome if (cp == optarg) {
411*22028508SToomas Soome snprintf(command_errbuf,
412*22028508SToomas Soome sizeof (command_errbuf),
413*22028508SToomas Soome "bad timeout '%s'", optarg);
414*22028508SToomas Soome return (CMD_ERROR);
415*22028508SToomas Soome }
416*22028508SToomas Soome break;
417*22028508SToomas Soome default:
418*22028508SToomas Soome return (CMD_OK);
419*22028508SToomas Soome }
420*22028508SToomas Soome }
421*22028508SToomas Soome
422*22028508SToomas Soome argv += (optind);
423*22028508SToomas Soome argc -= (optind);
424*22028508SToomas Soome name = (argc > 0) ? argv[0]: NULL;
425*22028508SToomas Soome
426*22028508SToomas Soome if (prompt != NULL)
427*22028508SToomas Soome printf("%s", prompt);
428*22028508SToomas Soome if (timeout >= 0) {
429*22028508SToomas Soome when = time(NULL) + timeout;
430*22028508SToomas Soome while (!ischar())
431*22028508SToomas Soome if (time(NULL) >= when)
432*22028508SToomas Soome return (CMD_OK); /* is timeout an error? */
433*22028508SToomas Soome }
434*22028508SToomas Soome
435*22028508SToomas Soome ngets(buf, sizeof (buf));
436*22028508SToomas Soome
437*22028508SToomas Soome if (name != NULL)
438*22028508SToomas Soome setenv(name, buf, 1);
439*22028508SToomas Soome return (CMD_OK);
440*22028508SToomas Soome }
441*22028508SToomas Soome
442*22028508SToomas Soome /*
443*22028508SToomas Soome * File pager
444*22028508SToomas Soome */
445*22028508SToomas Soome COMMAND_SET(more, "more", "show contents of a file", command_more);
446*22028508SToomas Soome
447*22028508SToomas Soome static int
command_more(int argc,char * argv[])448*22028508SToomas Soome command_more(int argc, char *argv[])
449*22028508SToomas Soome {
450*22028508SToomas Soome int i;
451*22028508SToomas Soome int res;
452*22028508SToomas Soome char line[80];
453*22028508SToomas Soome
454*22028508SToomas Soome res = 0;
455*22028508SToomas Soome pager_open();
456*22028508SToomas Soome for (i = 1; (i < argc) && (res == 0); i++) {
457*22028508SToomas Soome snprintf(line, sizeof (line), "*** FILE %s BEGIN ***\n",
458*22028508SToomas Soome argv[i]);
459*22028508SToomas Soome if (pager_output(line))
460*22028508SToomas Soome break;
461*22028508SToomas Soome res = page_file(argv[i]);
462*22028508SToomas Soome if (!res) {
463*22028508SToomas Soome snprintf(line, sizeof (line), "*** FILE %s END ***\n",
464*22028508SToomas Soome argv[i]);
465*22028508SToomas Soome res = pager_output(line);
466*22028508SToomas Soome }
467*22028508SToomas Soome }
468*22028508SToomas Soome pager_close();
469*22028508SToomas Soome
470*22028508SToomas Soome if (res == 0)
471*22028508SToomas Soome return (CMD_OK);
472*22028508SToomas Soome else
473*22028508SToomas Soome return (CMD_ERROR);
474*22028508SToomas Soome }
475*22028508SToomas Soome
476*22028508SToomas Soome static int
page_file(char * filename)477*22028508SToomas Soome page_file(char *filename)
478*22028508SToomas Soome {
479*22028508SToomas Soome int result;
480*22028508SToomas Soome
481*22028508SToomas Soome result = pager_file(filename);
482*22028508SToomas Soome
483*22028508SToomas Soome if (result == -1) {
484*22028508SToomas Soome snprintf(command_errbuf, sizeof (command_errbuf),
485*22028508SToomas Soome "error showing %s", filename);
486*22028508SToomas Soome }
487*22028508SToomas Soome
488*22028508SToomas Soome return (result);
489*22028508SToomas Soome }
490*22028508SToomas Soome
491*22028508SToomas Soome /*
492*22028508SToomas Soome * List all disk-like devices
493*22028508SToomas Soome */
494*22028508SToomas Soome COMMAND_SET(lsdev, "lsdev", "list all devices", command_lsdev);
495*22028508SToomas Soome
496*22028508SToomas Soome static int
command_lsdev(int argc,char * argv[])497*22028508SToomas Soome command_lsdev(int argc, char *argv[])
498*22028508SToomas Soome {
499*22028508SToomas Soome int verbose, ch, i;
500*22028508SToomas Soome char line[80];
501*22028508SToomas Soome
502*22028508SToomas Soome verbose = 0;
503*22028508SToomas Soome optind = 1;
504*22028508SToomas Soome optreset = 1;
505*22028508SToomas Soome while ((ch = getopt(argc, argv, "v")) != -1) {
506*22028508SToomas Soome switch (ch) {
507*22028508SToomas Soome case 'v':
508*22028508SToomas Soome verbose = 1;
509*22028508SToomas Soome break;
510*22028508SToomas Soome case '?':
511*22028508SToomas Soome default:
512*22028508SToomas Soome /* getopt has already reported an error */
513*22028508SToomas Soome return (CMD_OK);
514*22028508SToomas Soome }
515*22028508SToomas Soome }
516*22028508SToomas Soome argv += (optind);
517*22028508SToomas Soome argc -= (optind);
518*22028508SToomas Soome
519*22028508SToomas Soome pager_open();
520*22028508SToomas Soome for (i = 0; devsw[i] != NULL; i++) {
521*22028508SToomas Soome if (devsw[i]->dv_print != NULL) {
522*22028508SToomas Soome if (devsw[i]->dv_print(verbose))
523*22028508SToomas Soome break;
524*22028508SToomas Soome } else {
525*22028508SToomas Soome snprintf(line, sizeof (line), "%s: (unknown)\n",
526*22028508SToomas Soome devsw[i]->dv_name);
527*22028508SToomas Soome if (pager_output(line))
528*22028508SToomas Soome break;
529*22028508SToomas Soome }
530*22028508SToomas Soome }
531*22028508SToomas Soome pager_close();
532*22028508SToomas Soome return (CMD_OK);
533*22028508SToomas Soome }
534