commands.c revision 40015
1179189Sjb/*- 2179189Sjb * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3321268Sngie * All rights reserved. 4321268Sngie * 5179189Sjb * Redistribution and use in source and binary forms, with or without 6179189Sjb * modification, are permitted provided that the following conditions 7179189Sjb * are met: 8179189Sjb * 1. Redistributions of source code must retain the above copyright 9179189Sjb * notice, this list of conditions and the following disclaimer. 10179189Sjb * 2. Redistributions in binary form must reproduce the above copyright 11179189Sjb * notice, this list of conditions and the following disclaimer in the 12179189Sjb * documentation and/or other materials provided with the distribution. 13179189Sjb * 14179189Sjb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15179189Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16179189Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17179189Sjb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18179189Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19179189Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20179189Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21211554Srpaulo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22179189Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23179189Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24179189Sjb * SUCH DAMAGE. 25179189Sjb * 26179189Sjb * $Id: commands.c,v 1.3 1998/09/18 02:01:38 msmith Exp $ 27179189Sjb */ 28179189Sjb 29179189Sjb#include <stand.h> 30179189Sjb#include <string.h> 31179189Sjb#include <sys/reboot.h> 32179189Sjb 33179189Sjb#include "bootstrap.h" 34250574Smarkj 35179189Sjbchar *command_errmsg; 36248708Spfgchar command_errbuf[256]; /* XXX should have procedural interface for setting, size limit? */ 37179189Sjb 38179189SjbCOMMAND_SET(help, "help", "detailed help", command_help); 39179189Sjb 40179189Sjbstatic int 41179189Sjbcommand_help(int argc, char *argv[]) 42179189Sjb{ 43179189Sjb char helppath[80]; /* XXX buffer size? */ 44179189Sjb 45179189Sjb /* page the help text from our load path */ 46179189Sjb sprintf(helppath, "%s/boot/boot.help", getenv("loaddev")); 47233415Sgonzo printf("%s\n", helppath); 48179189Sjb if (pager_file(helppath) == -1) 49179189Sjb printf("Verbose help not available, use '?' to list commands\n"); 50238366Sgnn return(CMD_OK); 51254889Smarkj} 52179189Sjb 53283026SmarkjCOMMAND_SET(commandlist, "?", "list commands", command_commandlist); 54179189Sjb 55254889Smarkjstatic int 56323814Sgnncommand_commandlist(int argc, char *argv[]) 57254889Smarkj{ 58179189Sjb struct bootblk_command **cmdp; 59179189Sjb int i; 60287971Sbdrewery 61287971Sbdrewery printf("Available commands:\n"); 62287971Sbdrewery cmdp = (struct bootblk_command **)Xcommand_set.ls_items; 63287971Sbdrewery for (i = 0; i < Xcommand_set.ls_length; i++) 64204597Suqs if ((cmdp[i]->c_name != NULL) && (cmdp[i]->c_desc != NULL)) 65179189Sjb printf(" %-15s %s\n", cmdp[i]->c_name, cmdp[i]->c_desc); 66211554Srpaulo return(CMD_OK); 67321268Sngie} 68321268Sngie 69321268Sngie/* 70179189Sjb * XXX set/show should become set/echo if we have variable 71179189Sjb * substitution happening. 72179189Sjb */ 73179189Sjb 74179189SjbCOMMAND_SET(show, "show", "show variable(s)", command_show); 75179189Sjb 76179189Sjbstatic int 77285009Sbrcommand_show(int argc, char *argv[]) 78285009Sbr{ 79321268Sngie struct env_var *ev; 80321268Sngie char *cp; 81285009Sbr 82321268Sngie if (argc < 2) { 83211554Srpaulo /* 84321268Sngie * With no arguments, print everything. 85321268Sngie */ 86321268Sngie pager_open(); 87285009Sbr for (ev = environ; ev != NULL; ev = ev->ev_next) { 88285009Sbr pager_output(ev->ev_name); 89321268Sngie cp = getenv(ev->ev_name); 90321268Sngie if (cp != NULL) { 91233415Sgonzo pager_output("="); 92233415Sgonzo pager_output(cp); 93321268Sngie } 94321268Sngie pager_output("\n"); 95242723Sjhibbits } 96242723Sjhibbits pager_close(); 97321268Sngie } else { 98321268Sngie if ((cp = getenv(argv[1])) != NULL) { 99300618Sbr printf("%s\n", cp); 100300618Sbr } else { 101321268Sngie sprintf(command_errbuf, "variable '%s' not found", argv[1]); 102321268Sngie return(CMD_ERROR); 103285009Sbr } 104285009Sbr } 105321268Sngie return(CMD_OK); 106179189Sjb} 107179189Sjb 108179189SjbCOMMAND_SET(set, "set", "set a variable", command_set); 109179189Sjb 110179189Sjbstatic int 111211554Srpaulocommand_set(int argc, char *argv[]) 112233415Sgonzo{ 113211554Srpaulo int err; 114211554Srpaulo 115211554Srpaulo if (argc != 2) { 116179189Sjb command_errmsg = "wrong number of arguments"; 117179189Sjb return(CMD_ERROR); 118179189Sjb } else { 119179189Sjb if ((err = putenv(argv[1])) != 0) { 120283133Sbapt command_errmsg = strerror(err); 121283133Sbapt return(CMD_ERROR); 122179189Sjb } 123179189Sjb } 124313131Smarkj return(CMD_OK); 125179189Sjb} 126313131Smarkj 127313131SmarkjCOMMAND_SET(unset, "unset", "unset a variable", command_unset); 128179189Sjb 129313131Smarkjstatic int 130313131Smarkjcommand_unset(int argc, char *argv[]) 131{ 132 int err; 133 134 if (argc != 2) { 135 command_errmsg = "wrong number of arguments"; 136 return(CMD_ERROR); 137 } else { 138 if ((err = unsetenv(argv[1])) != 0) { 139 command_errmsg = strerror(err); 140 return(CMD_ERROR); 141 } 142 } 143 return(CMD_OK); 144} 145 146COMMAND_SET(echo, "echo", NULL, command_echo); 147 148static int 149command_echo(int argc, char *argv[]) 150{ 151 char *s; 152 int nl, ch; 153 154 nl = 0; 155 optind = 1; 156 while ((ch = getopt(argc, argv, "n")) != -1) { 157 switch(ch) { 158 case 'n': 159 nl = 1; 160 break; 161 case '?': 162 default: 163 /* getopt has already reported an error */ 164 return(CMD_OK); 165 } 166 } 167 argv += (optind); 168 argc -= (optind); 169 170 s = unargv(argc, argv); 171 if (s != NULL) { 172 printf(s); 173 free(s); 174 } 175 if (!nl) 176 printf("\n"); 177 return(CMD_OK); 178} 179 180/* 181 * A passable emulation of the sh(1) command of the same name. 182 */ 183 184COMMAND_SET(read, "read", NULL, command_read); 185 186static int 187command_read(int argc, char *argv[]) 188{ 189 char *prompt; 190 int timeout; 191 time_t when; 192 char *cp; 193 char *name; 194 char buf[256]; /* XXX size? */ 195 int c; 196 197 timeout = -1; 198 prompt = NULL; 199 optind = 1; 200 while ((c = getopt(argc, argv, "p:t:")) != -1) { 201 switch(c) { 202 203 case 'p': 204 prompt = optarg; 205 break; 206 case 't': 207 timeout = strtol(optarg, &cp, 0); 208 if (cp == optarg) { 209 sprintf(command_errbuf, "bad timeout '%s'", optarg); 210 return(CMD_ERROR); 211 } 212 break; 213 default: 214 return(CMD_OK); 215 } 216 } 217 218 argv += (optind); 219 argc -= (optind); 220 name = (argc > 0) ? argv[0]: NULL; 221 222 if (prompt != NULL) 223 printf(prompt); 224 if (timeout >= 0) { 225 when = time(NULL) + timeout; 226 while (!ischar()) 227 if (time(NULL) >= when) 228 return(CMD_OK); /* is timeout an error? */ 229 } 230 231 ngets(buf, sizeof(buf)); 232 233 printf("read name '%s' value '%s'\n", name, buf); 234 235 if (name != NULL) 236 setenv(name, buf, 1); 237 return(CMD_OK); 238} 239