sprintf(cmd.path, "%s:%s%s", cmd.bootdev, cmd.cwd, cmd.image);
sprintf(cmd.path, "%s:%s", cmd.bootdev, cmd.image);
static char *qualify __P((char *));static char cmd_buf[133];intgetcmd(){	cmd.cmd = NULL;	if (!readline(cmd_buf, cmd.timeout))		cmd.cmd = cmd_table;	return docmd();}intread_conf(){#ifndef INSECURE	struct stat sb;#endif	int fd, eof = 0;	if ((fd = open(qualify(cmd.conf), 0)) < 0) {		if (errno != ENOENT && errno != ENXIO) {			printf("open(%s): %s\n", cmd.path, strerror(errno));			return 0;		}		return -1;	}#ifndef INSECURE	(void) fstat(fd, &sb);	if (sb.st_uid || (sb.st_mode & 2)) {		printf("non-secure %s, will not proceed\n", cmd.path);		close(fd);		return -1;	}#endif	do {		register char *p = cmd_buf;		cmd.cmd = NULL;		do			eof = read(fd, p, 1);		while (eof > 0 && *p++ != '\n');		if (eof < 0)			printf("%s: %s\n", cmd.path, strerror(errno));		else			*--p = '\0';	} while (eof > 0 && !(eof = docmd()));	close(fd);	return eof;}static intdocmd(){	const struct cmd_table *ct;	register char *p = NULL;	cmd.argc = 1;	if (cmd.cmd == NULL) {		/* command */		for (p = cmd_buf; *p && (*p == ' ' || *p == '\t'); p++)			;		if (*p == '#' || *p == '\0') { /* comment or empty string */#ifdef DEBUG			printf("rem\n");#endif			return 0;		}		ct = cmd_table;		cmd.argv[cmd.argc] = p; /* in case it's shortcut boot */		p = whatcmd(&ct, p);		if (ct == NULL) {			cmd.argc++;			ct = cmd_table;		} else if (ct->cmd_type == CMDT_SET && p != NULL) {			const struct cmd_table *cs = cmd_set;			p = whatcmd(&cs, p);			if (cs == NULL) {				printf("%s: syntax error\n", ct->cmd_name);				return 0;			}			ct = cs;		}		cmd.cmd = ct;	}	cmd.argv[0] = ct->cmd_name;	while (p && cmd.argc+1 < sizeof(cmd.argv) / sizeof(cmd.argv[0])) {		cmd.argv[cmd.argc++] = p;		p = nextword(p);	}	cmd.argv[cmd.argc] = NULL;	return (*cmd.cmd->cmd_exec)();}static char *whatcmd(ct, p)	register const struct cmd_table **ct;	register char *p;{	register char *q;	register int l;	q = nextword(p);	for (l = 0; p[l]; l++)		;	while ((*ct)->cmd_name != NULL && strncmp(p, (*ct)->cmd_name, l))		(*ct)++;	if ((*ct)->cmd_name == NULL)		*ct = NULL;	return q;}static intreadline(buf, to)	register char *buf;	int	to;{	register char *p = buf, *pe = buf, ch;	time_t tt;	for (tt = getsecs() + to; getsecs() < tt && !cnischar(); )		;	if (!cnischar())		return 0;	while (1) {		switch ((ch = getchar())) {		case CTRL('r'):			while (pe > buf)				putchar('\177');			printf(buf);		case CTRL('u'):			while (pe >= buf) {				pe--;				putchar('\177');			}			p = pe = buf;			continue;		case '\n':		case '\r':			pe[1] = *pe = '\0';			break;		case '\b':		case '\177':			if (p > buf) {				putchar('\177');				p--;				pe--;			}			continue;		default:			pe++;			*p++ = ch;			continue;		}		break;	}	return pe - buf;}/* * Search for spaces/tabs after the current word. If found, \0 the * first one.  Then pass a pointer to the first character of the * next word, or NULL if there is no next word.  */char *nextword(p)	register char *p;{	/* skip blanks */	while (*p && *p != '\t' && *p != ' ')		p++;	if (*p) {		*p++ = '\0';		while (*p == '\t' || *p == ' ')			p++;	}	if (*p == '\0')		p = NULL;	return p;}#ifdef DEBUGstatic intXdebug(){	if (cmd.argc !=2)		printf(debug? "on": "off");	else		debug = (cmd.argv[1][0] == '0' ||			 (cmd.argv[1][0] == 'o' && cmd.argv[1][1] == 'f'))?			 0: 1;	return 0;}#endifstatic intXhelp(){	register const struct cmd_table *ct;	printf("commands:");	for (ct = cmd_table; ct->cmd_name != NULL; ct++)		printf(" %s", ct->cmd_name);	putchar('\n');	return 0;}static intXecho(){	register int i;	for (i = 1; i < cmd.argc; i++)		printf(cmd.argv[i]), putchar(' ');	putchar('\n');	return 0;}/* called only w/ no arguments */static intXset(){	register const struct cmd_table *ct;	printf("OpenBSD boot[%s]\n", version);	printf("cwd\t%s\n", cmd.cwd);	for (ct = cmd_set; ct->cmd_name != NULL; ct++) {		printf("%s\t ", ct->cmd_name);		(*ct->cmd_exec)();		putchar('\n');	}	return 0;}static intXdevice(){	if (cmd.argc != 2)		printf(cmd.bootdev);	else		strncpy(cmd.bootdev, cmd.argv[1], sizeof(cmd.bootdev));	return 0;}static intXimage(){	if (cmd.argc != 2)		printf(cmd.image);	else		strncpy(cmd.image, cmd.argv[1], sizeof(cmd.image));	return 0;}static intXaddr(){	register char *p;	if (cmd.argc != 2)		printf("%p", cmd.addr);	else {		register u_long a;		p = cmd.argv[1];		if (p[0] == '0' && p[1] == 'x')			p += 2;		for (a = 0; *p != '\0'; p++) {			a <<= 4;			a |= (isdigit(*p)? *p - '0':			      10 + tolower(*p) - 'a') & 0xf;		}		cmd.addr = (void *)a;	}	return 0;}static intXtty(){	dev_t dev;	if (cmd.argc == 1)		printf(ttyname(0));	else {		dev = ttydev(cmd.argv[1]);		if (dev == NODEV)			printf("%s not a console device\n", cmd.argv[1]);		else if (cnset(dev))			printf("%s console not present\n", cmd.argv[1]);	}	return 0;}static intXtime(){	if (cmd.argc == 1)		time_print();	else {	}	return 0;}static intXls(){	struct stat sb;	register char *p;	int fd;	if (stat(qualify((cmd.argv[1]? cmd.argv[1]: "/.")), &sb) < 0) {		printf("stat(%s): %s\n", cmd.path, strerror(errno));		return 0;	}	if ((sb.st_mode & S_IFMT) != S_IFDIR)		ls(cmd.path, &sb);	else {		if ((fd = opendir(cmd.path)) < 0) {			printf ("opendir(%s): %s\n", cmd.path,				strerror(errno));			return 0;		}		/* no strlen in lib !!! */		for (p = cmd.path; *p; p++);		*p++ = '/';		*p = '\0';		while(readdir(fd, p) >= 0) {			if (stat(cmd.path, &sb) < 0)				printf("stat(%s): %s\n", cmd.path,				       strerror(errno));			else				ls(p, &sb);		}		closedir (fd);	}	return 0;}#define lsrwx(mode,s) \	putchar ((mode) & S_IROTH? 'r' : '-'); \	putchar ((mode) & S_IWOTH? 'w' : '-'); \	putchar ((mode) & S_IXOTH? *(s): (s)[1]);static voidls(name, sb)	register char *name;	register struct stat *sb;{	putchar("-fc-d-b---l-s-w-"[(sb->st_mode & S_IFMT) >> 12]);	lsrwx(sb->st_mode >> 6, (sb->st_mode & S_ISUID? "sS" : "x-"));	lsrwx(sb->st_mode >> 3, (sb->st_mode & S_ISUID? "sS" : "x-"));	lsrwx(sb->st_mode     , (sb->st_mode & S_ISTXT? "tT" : "x-"));	printf (" %u,%u\t%lu\t%s\n", sb->st_uid, sb->st_gid,		(u_long)sb->st_size, name);}#undef lsrwxstatic intXhowto(){	if (cmd.argc < 2) {		if (cmd.boothowto) {			putchar('-');			if (cmd.boothowto & RB_ASKNAME)				putchar('a');			if (cmd.boothowto & RB_HALT)				putchar('b');			if (cmd.boothowto & RB_CONFIG)				putchar('c');			if (cmd.boothowto & RB_SINGLE)				putchar('s');			if (cmd.boothowto & RB_KDB)				putchar('d');		}	} else		bootparse(1);	return 0;}static intXboot(){	if (cmd.argc > 1 && cmd.argv[1][0] != '-') {		qualify((cmd.argv[1]? cmd.argv[1]: cmd.image));		if (bootparse(2))			return 0;	} else {		if (bootparse(1))			return 0;		sprintf(cmd.path, "%s:%s%s", cmd.bootdev, cmd.cwd, cmd.image);	}	return 1;}/* * Qualifies the path adding neccessary dev&|cwd */static char *qualify(name)	char *name;{	register char *p;	for (p = name; *p; p++)		if (*p == ':')			break;	if (*p == ':')		if (p[1] == '/')			sprintf(cmd.path, "%s", name);		else			sprintf(cmd.path, "%s%s", cmd.cwd, name);	else if (name[0] == '/')		sprintf(cmd.path, "%s:%s", cmd.bootdev, name);	else		sprintf(cmd.path, "%s:%s%s", cmd.bootdev, cmd.cwd, name);	return cmd.path;}