I'll have to see about trying this out on my zaurus.
Last time I checked, the boot> prompt ran in linux text console mode,
which means once you reach the last line, it scrolls on the last line,
and the rest of the screen is locked. Highly inconvenient without clear.
Hmm..
Penned by Tobias Stoeckmann on 20140711 11:30.20, we have:
| Anyone?
|
| On Fri, Jul 04, 2014 at 07:41:07PM +0200, Tobias Stoeckmann wrote:
| > On Sun, Jun 29, 2014 at 08:40:53PM +0200, Tobias Stoeckmann wrote:
| > > "cc -c" works for zaurus' cmd.c. I don't have a zaurus, so it would be
| > > nice if a zaurus owner can test these changes.
| >
| > Got feedback from zaurus users. The Makefile was missing another change:
| > It still listed cmd.c in SRCS. Compiles for them and nobody shouted at
| > me for removing "clear".
| >
| > Patch updated, I also incremented zboot to 2.10, after all this diff
| > will zap the "clear" command.
| >
| > Okay?
| >
| > Index: arch/zaurus/stand/zboot/Makefile
| > ===================================================================
| > RCS file: /cvs/src/sys/arch/zaurus/stand/zboot/Makefile,v
| > retrieving revision 1.13
| > diff -u -p -r1.13 Makefile
| > --- arch/zaurus/stand/zboot/Makefile 10 Sep 2013 21:00:26 -0000
1.13
| > +++ arch/zaurus/stand/zboot/Makefile 4 Jul 2014 17:39:53 -0000
| > @@ -21,7 +21,7 @@ CLEANFILES+= arm machine
| > .endif
| >
| > # stand/boot
| > -SRCS+= boot.c vars.c bootarg.c conf.c
| > +SRCS+= boot.c cmd.c vars.c bootarg.c conf.c
| >
| > # libsa
| > SRCS+= close.c closeall.c cons.c ctime.c disklabel.c dkcksum.c fstat.c
\
| > @@ -33,7 +33,7 @@ SRCS+= strcmp.c strlcpy.c strlen.c strnc
| > ashrdi3.c divsi3.S divdi3.c moddi3.c qdivrem.c
| >
| > # local overrides and additions
| > -SRCS+= alloc.c cmd.c devopen.c diskprobe.c exec.c exit.c loadfile.c \
| > +SRCS+= alloc.c devopen.c diskprobe.c exec.c exit.c loadfile.c \
| > machdep.c termios.c unixcons.c unixdev.c unixsys.S
| >
| > .PATH: ${S}/stand/boot
| > Index: arch/zaurus/stand/zboot/boot.8
| > ===================================================================
| > RCS file: /cvs/src/sys/arch/zaurus/stand/zboot/boot.8,v
| > retrieving revision 1.10
| > diff -u -p -r1.10 boot.8
| > --- arch/zaurus/stand/zboot/boot.8 27 Sep 2012 12:26:28 -0000 1.10
| > +++ arch/zaurus/stand/zboot/boot.8 4 Jul 2014 17:39:53 -0000
| > @@ -103,6 +103,12 @@ This file may contain any commands
| > .Nm
| > accepts at the interactive prompt.
| > Though default settings usually suffice, they can be changed here.
| > +.\" XXX CHECK_SKIP_CONF is not defined...
| > +.\" .Pp
| > +.\" .Pa boot.conf
| > +.\" processing can be skipped by holding down either Control key as
| > +.\" .Nm
| > +.\" starts.
| > .It
| > The header line
| > .Pp
| > Index: arch/zaurus/stand/zboot/cmd.c
| > ===================================================================
| > RCS file: arch/zaurus/stand/zboot/cmd.c
| > diff -N arch/zaurus/stand/zboot/cmd.c
| > --- arch/zaurus/stand/zboot/cmd.c 21 Mar 2007 03:29:05 -0000 1.3
| > +++ /dev/null 1 Jan 1970 00:00:00 -0000
| > @@ -1,532 +0,0 @@
| > -/* $OpenBSD: cmd.c,v 1.3 2007/03/21 03:29:05 tedu Exp $ */
| > -
| > -/*
| > - * Copyright (c) 1997-1999 Michael Shalayeff
| > - * All rights reserved.
| > - *
| > - * Redistribution and use in source and binary forms, with or without
| > - * modification, are permitted provided that the following conditions
| > - * are met:
| > - * 1. Redistributions of source code must retain the above copyright
| > - * notice, this list of conditions and the following disclaimer.
| > - * 2. Redistributions in binary form must reproduce the above copyright
| > - * notice, this list of conditions and the following disclaimer in the
| > - * documentation and/or other materials provided with the distribution.
| > - *
| > - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
| > - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
| > - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
| > - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
| > - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL
| > - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
| > - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
| > - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT
| > - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
WAY
| > - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
| > - * SUCH DAMAGE.
| > - */
| > -
| > -#include <sys/param.h>
| > -#include <sys/reboot.h>
| > -
| > -#ifdef REGRESS
| > -#include <sys/stat.h>
| > -#include <errno.h>
| > -#else
| > -#include <libsa.h>
| > -#include <lib/libkern/funcs.h>
| > -#endif
| > -
| > -#include <stand/boot/cmd.h>
| > -
| > -#define CTRL(c) ((c)&0x1f)
| > -
| > -static int Xboot(void);
| > -static int Xclear(void);
| > -static int Xecho(void);
| > -static int Xhelp(void);
| > -static int Xls(void);
| > -static int Xnop(void);
| > -static int Xreboot(void);
| > -static int Xstty(void);
| > -static int Xtime(void);
| > -#ifdef MACHINE_CMD
| > -static int Xmachine(void);
| > -extern const struct cmd_table MACHINE_CMD[];
| > -#endif
| > -extern int Xset(void);
| > -extern int Xenv(void);
| > -
| > -extern const struct cmd_table cmd_set[];
| > -const struct cmd_table cmd_table[] = {
| > - {"#", CMDT_CMD, Xnop}, /* XXX must be first */
| > - {"boot", CMDT_CMD, Xboot},
| > - {"clear", CMDT_CMD, Xclear},
| > - {"echo", CMDT_CMD, Xecho},
| > - {"env", CMDT_CMD, Xenv},
| > - {"help", CMDT_CMD, Xhelp},
| > - {"ls", CMDT_CMD, Xls},
| > -#ifdef MACHINE_CMD
| > - {"machine",CMDT_MDC, Xmachine},
| > -#endif
| > - {"reboot", CMDT_CMD, Xreboot},
| > - {"set", CMDT_SET, Xset},
| > - {"stty", CMDT_CMD, Xstty},
| > - {"time", CMDT_CMD, Xtime},
| > - {NULL, 0},
| > -};
| > -
| > -static void ls(char *, struct stat *);
| > -static int readline(char *, size_t, int);
| > -char *nextword(char *);
| > -static char *whatcmd(const struct cmd_table **ct, char *);
| > -static char *qualify(char *);
| > -
| > -char cmd_buf[CMD_BUFF_SIZE];
| > -
| > -int
| > -getcmd(void)
| > -{
| > - cmd.cmd = NULL;
| > -
| > - if (!readline(cmd_buf, sizeof(cmd_buf), cmd.timeout))
| > - cmd.cmd = cmd_table;
| > -
| > - return docmd();
| > -}
| > -
| > -int
| > -read_conf(void)
| > -{
| > -#ifndef INSECURE
| > - struct stat sb;
| > -#endif
| > - int fd, rc = 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 {
| > - char *p = cmd_buf;
| > -
| > - cmd.cmd = NULL;
| > - do {
| > - rc = read(fd, p, 1);
| > - } while (rc > 0 && *p++ != '\n' &&
| > - (p-cmd_buf) < sizeof(cmd_buf));
| > -
| > - if (rc < 0) { /* Error from read() */
| > - printf("%s: %s\n", cmd.path, strerror(errno));
| > - break;
| > - }
| > -
| > - if (rc == 0) { /* eof from read() */
| > - if (p != cmd_buf) { /* Line w/o trailing \n */
| > - *p = '\0';
| > - rc = docmd();
| > - break;
| > - }
| > - } else { /* rc > 0, read a char */
| > - p--; /* Get back to last character */
| > -
| > - if (*p != '\n') { /* Line was too long */
| > - printf("%s: line too long\n", cmd.path);
| > -
| > - /* Don't want to run the truncated command */
| > - rc = -1;
| > - }
| > - *p = '\0';
| > - }
| > - } while (rc > 0 && !(rc = docmd()));
| > -
| > - close(fd);
| > - return rc;
| > -}
| > -
| > -int
| > -docmd(void)
| > -{
| > - char *p = NULL;
| > - const struct cmd_table *ct = cmd_table, *cs;
| > -
| > - cmd.argc = 1;
| > - if (cmd.cmd == NULL) {
| > -
| > - /* command */
| > - for (p = cmd_buf; *p == ' ' || *p == '\t'; p++)
| > - ;
| > - if (*p == '#' || *p == '\0') { /* comment or empty string */
| > -#ifdef DEBUG
| > - printf("rem\n");
| > -#endif
| > - return 0;
| > - }
| > - ct = cmd_table;
| > - cs = NULL;
| > - 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) {
| > - cs = cmd_set;
| > -#ifdef MACHINE_CMD
| > - } else if (ct->cmd_type == CMDT_MDC && p != NULL) {
| > - cs = MACHINE_CMD;
| > -#endif
| > - }
| > -
| > - if (cs != NULL) {
| > - 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;
| > -
| > -#ifdef REGRESS
| > - printf("%s %s\n", cmd.argv[0],
| > - (cmd.argv[1] == NULL) ? "(null)" : cmd.argv[1]);
| > -#else
| > - return (*cmd.cmd->cmd_exec)();
| > -#endif
| > -}
| > -
| > -static char *
| > -whatcmd(const struct cmd_table **ct, char *p)
| > -{
| > - char *q;
| > - 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 int
| > -readline(char *buf, size_t n, int to)
| > -{
| > -#ifdef DEBUG
| > - extern int debug;
| > -#endif
| > - char *p = buf, ch;
| > -
| > - /* Only do timeout if greater than 0 */
| > - if (to > 0) {
| > - u_long i = 0;
| > - time_t tt = getsecs() + to;
| > -#ifdef DEBUG
| > - if (debug > 2)
| > - printf ("readline: timeout(%d) at %u\n", to, tt);
| > -#endif
| > - /* check for timeout expiration less often
| > - (for some very constrained archs) */
| > - while (!cnischar())
| > - if (!(i++ % 1000) && (getsecs() >= tt))
| > - break;
| > -
| > - if (!cnischar()) {
| > - strlcpy(buf, "boot", 5);
| > - putchar('\n');
| > - return strlen(buf);
| > - }
| > - } else
| > - while (!cnischar())
| > - ;
| > -
| > - /* User has typed something. Turn off timeouts. */
| > - cmd.timeout = 0;
| > -
| > - while (1) {
| > - switch ((ch = getchar())) {
| > - case CTRL('u'):
| > - while (p > buf) {
| > - putchar('\177');
| > - p--;
| > - }
| > - continue;
| > - case '\n':
| > - case '\r':
| > - p[1] = *p = '\0';
| > - break;
| > - case '\b':
| > - case '\177':
| > - if (p > buf) {
| > - putchar('\177');
| > - p--;
| > - }
| > - continue;
| > - default:
| > - if (p - buf < n-1)
| > - *p++ = ch;
| > - else {
| > - putchar('\007');
| > - putchar('\177');
| > - }
| > - continue;
| > - }
| > - break;
| > - }
| > -
| > - return p - 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(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;
| > -}
| > -
| > -static void
| > -print_help(const struct cmd_table *ct)
| > -{
| > - for (; ct->cmd_name != NULL; ct++)
| > - printf(" %s", ct->cmd_name);
| > - putchar('\n');
| > -}
| > -
| > -static int
| > -Xhelp(void)
| > -{
| > - printf("commands:");
| > - print_help(cmd_table);
| > -#ifdef MACHINE_CMD
| > - return Xmachine();
| > -#else
| > - return 0;
| > -#endif
| > -}
| > -
| > -#ifdef MACHINE_CMD
| > -static int
| > -Xmachine(void)
| > -{
| > - printf("machine:");
| > - print_help(MACHINE_CMD);
| > - return 0;
| > -}
| > -#endif
| > -
| > -static int
| > -Xclear(void)
| > -{
| > - int i;
| > -
| > - printf("\033[H\033[J");
| > - return 0;
| > -}
| > -
| > -static int
| > -Xecho(void)
| > -{
| > - int i;
| > -
| > - for (i = 1; i < cmd.argc; i++)
| > - printf("%s ", cmd.argv[i]);
| > - putchar('\n');
| > - return 0;
| > -}
| > -
| > -static int
| > -Xstty(void)
| > -{
| > - int sp;
| > - char *cp;
| > - dev_t dev;
| > -
| > - if (cmd.argc == 1) {
| > - printf("%s speed is %d\n", ttyname(0), cnspeed(0, -1));
| > - return 0;
| > - }
| > - dev = ttydev(cmd.argv[1]);
| > - if (dev == NODEV) {
| > - printf("%s not a console device\n", cmd.argv[1]);
| > - return 0;
| > - }
| > -
| > - if (cmd.argc == 2)
| > - printf("%s speed is %d\n", cmd.argv[1],
| > - cnspeed(dev, -1));
| > - else {
| > - sp = 0;
| > - for (cp = cmd.argv[2]; isdigit(*cp); cp++)
| > - sp = sp * 10 + (*cp - '0');
| > - cnspeed(dev, sp);
| > - }
| > - return 0;
| > -}
| > -
| > -static int
| > -Xtime(void)
| > -{
| > - time_t tt = getsecs();
| > -
| > - if (cmd.argc == 1)
| > - printf(ctime(&tt));
| > -
| > - return 0;
| > -}
| > -
| > -static int
| > -Xls(void)
| > -{
| > - struct stat sb;
| > - 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 void
| > -ls(char *name, 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_ISGID? "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 lsrwx
| > -
| > -int doboot = 1;
| > -
| > -static int
| > -Xnop(void)
| > -{
| > - if (doboot) {
| > - doboot = 0;
| > - return (Xboot());
| > - }
| > -
| > - return 0;
| > -}
| > -
| > -static int
| > -Xboot(void)
| > -{
| > - 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;
| > - snprintf(cmd.path, sizeof cmd.path, "%s:%s",
| > - cmd.bootdev, cmd.image);
| > - }
| > -
| > - return 1;
| > -}
| > -
| > -/*
| > - * Qualifies the path adding necessary dev
| > - */
| > -
| > -static char *
| > -qualify(char *name)
| > -{
| > - char *p;
| > -
| > - for (p = name; *p; p++)
| > - if (*p == ':')
| > - break;
| > - if (*p == ':')
| > - strlcpy(cmd.path, name, sizeof(cmd.path));
| > - else
| > - snprintf(cmd.path, sizeof cmd.path, "%s:%s",
| > - cmd.bootdev, name);
| > - return cmd.path;
| > -}
| > -
| > -static int
| > -Xreboot(void)
| > -{
| > - printf("Rebooting...\n");
| > - exit();
| > - return 0; /* just in case */
| > -}
| > -
| > Index: arch/zaurus/stand/zboot/conf.c
| > ===================================================================
| > RCS file: /cvs/src/sys/arch/zaurus/stand/zboot/conf.c,v
| > retrieving revision 1.8
| > diff -u -p -r1.8 conf.c
| > --- arch/zaurus/stand/zboot/conf.c 28 Dec 2013 02:53:04 -0000 1.8
| > +++ arch/zaurus/stand/zboot/conf.c 4 Jul 2014 17:39:53 -0000
| > @@ -42,7 +42,7 @@
| > #include "unixdev.h"
| > #include <dev/cons.h>
| >
| > -const char version[] = "2.09";
| > +const char version[] = "2.10";
| > int debug = 1;
| >
| > void (*zaurus_probe1[])(void) = {
| > Index: stand/boot/cmd.c
| > ===================================================================
| > RCS file: /cvs/src/sys/stand/boot/cmd.c,v
| > retrieving revision 1.62
| > diff -u -p -r1.62 cmd.c
| > --- stand/boot/cmd.c 27 Jun 2014 20:35:37 -0000 1.62
| > +++ stand/boot/cmd.c 4 Jul 2014 17:39:53 -0000
| > @@ -129,7 +129,6 @@ read_conf(void)
| > char *p = cmd_buf;
| >
| > cmd.cmd = NULL;
| > -
| > do {
| > rc = read(fd, p, 1);
| > } while (rc > 0 && *p++ != '\n' &&
| > @@ -155,10 +154,8 @@ read_conf(void)
| > /* Don't want to run the truncated command */
| > rc = -1;
| > }
| > -
| > *p = '\0';
| > }
| > -
| > } while (rc > 0 && !(rc = docmd()));
| >
| > close(fd);
| > @@ -378,25 +375,25 @@ Xstty(void)
| > char *cp;
| > dev_t dev;
| >
| > - if (cmd.argc == 1)
| > + if (cmd.argc == 1) {
| > printf("%s speed is %d\n", ttyname(0), cnspeed(0, -1));
| > - else {
| > - dev = ttydev(cmd.argv[1]);
| > - if (dev == NODEV)
| > - printf("%s not a console device\n", cmd.argv[1]);
| > - else {
| > - if (cmd.argc == 2)
| > - printf("%s speed is %d\n", cmd.argv[1],
| > - cnspeed(dev, -1));
| > - else {
| > - sp = 0;
| > - for (cp = cmd.argv[2]; *cp && isdigit(*cp);
cp++)
| > - sp = sp * 10 + (*cp - '0');
| > - cnspeed(dev, sp);
| > - }
| > - }
| > + return 0;
| > + }
| > + dev = ttydev(cmd.argv[1]);
| > + if (dev == NODEV) {
| > + printf("%s not a console device\n", cmd.argv[1]);
| > + return 0;
| > }
| >
| > + if (cmd.argc == 2)
| > + printf("%s speed is %d\n", cmd.argv[1],
| > + cnspeed(dev, -1));
| > + else {
| > + sp = 0;
| > + for (cp = cmd.argv[2]; isdigit(*cp); cp++)
| > + sp = sp * 10 + (*cp - '0');
| > + cnspeed(dev, sp);
| > + }
| > return 0;
| > }
| >
| > @@ -407,8 +404,6 @@ Xtime(void)
| >
| > if (cmd.argc == 1)
| > printf(ctime(&tt));
| > - else {
| > - }
| >
| > return 0;
| > }
| > @@ -429,8 +424,8 @@ Xls(void)
| > ls(cmd.path, &sb);
| > else {
| > if ((fd = opendir(cmd.path)) < 0) {
| > - printf ("opendir(%s): %s\n", cmd.path,
| > - strerror(errno));
| > + printf("opendir(%s): %s\n", cmd.path,
| > + strerror(errno));
| > return 0;
| > }
| >
| > @@ -440,10 +435,10 @@ Xls(void)
| > *p++ = '/';
| > *p = '\0';
| >
| > - while(readdir(fd, p) >= 0) {
| > + while (readdir(fd, p) >= 0) {
| > if (stat(cmd.path, &sb) < 0)
| > printf("stat(%s): %s\n", cmd.path,
| > - strerror(errno));
| > + strerror(errno));
| > else
| > ls(p, &sb);
| > }
--
Todd T. Fries . http://todd.fries.net/pgp.txt . @unix2mars . github:toddfries