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