From 606eff77a12131f877e872c53def49f8ace17783 Mon Sep 17 00:00:00 2001 From: Garrett Wollman Date: Fri, 14 Apr 1995 18:33:44 +0000 Subject: [PATCH] Add `-s' flag to permit selection of devices in accordance with their state (after all, who wants to be offered a menu of devices which weren't found?). --- usr.bin/devmenu/devfilter.c | 5 ++- usr.bin/devmenu/devmenu.1 | 38 ++++++++++++++++++++--- usr.bin/devmenu/devmenu.c | 61 ++++++++++++++++++++++++++++++++----- usr.bin/devmenu/devmenu.h | 14 ++++----- usr.bin/devmenu/ifmenu.c | 5 +-- 5 files changed, 100 insertions(+), 23 deletions(-) diff --git a/usr.bin/devmenu/devfilter.c b/usr.bin/devmenu/devfilter.c index d48a6b80aa34..9cfd3660f8d5 100644 --- a/usr.bin/devmenu/devfilter.c +++ b/usr.bin/devmenu/devfilter.c @@ -132,7 +132,8 @@ devmenu_freedevs(struct devconf ***devpp) const char * devmenu_common(const char *title, const char *hfile, char **devnames, - const char *prompt, const char *none, enum dc_class class) + const char *prompt, const char *none, enum dc_class class, + int states) { struct devconf **devs; int s; @@ -149,6 +150,8 @@ devmenu_common(const char *title, const char *hfile, char **devnames, devs = devmenu_alldevs(); for (i = 0; devs[i]; i++) { + if (states && !((1 << devs[i]->dc_state) & states)) + continue; if (class && !(devs[i]->dc_class & class)) continue; if (devmenu_filter(devs[i], devnames)) { diff --git a/usr.bin/devmenu/devmenu.1 b/usr.bin/devmenu/devmenu.1 index c1026260db00..f277baafb345 100644 --- a/usr.bin/devmenu/devmenu.1 +++ b/usr.bin/devmenu/devmenu.1 @@ -26,18 +26,19 @@ .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id$ -.Dd April 13, 1995 +.\" $Id: devmenu.1,v 1.1 1995/04/13 21:10:58 wollman Exp $ +.Dd April 14, 1995 .Dt DEVMENU 1 .Os FreeBSD 2.1 .Sh NAME .Nm devmenu .Nd present a menu of available devices .Sh SYNOPSIS -.Nm lsdev +.Nm devmenu .Op Fl c Ar class .Op Fl f Ar outfile .Op Fl h Ar helpfile +.Op Fl s Ar state .Op Fl t Ar title .Op Fl nid .Op Ar name ... @@ -52,7 +53,7 @@ criteria. The list of devices is obtained using the device configuration database .Pq Dq devconf , and intersected with the list of -.Ar name s +.No Ar name Ns s if one was specified on the command line. The following command-line flags are supported: .Bl -tag -width mhmhelpfile @@ -62,7 +63,8 @@ choices. Multiple .Fl c options can be specified, in which case the union of the specified classes is used. The following classes are currently supported: -.Bl -tag -width parallel +.Pp +.Bl -tag -compact -width parallel .It Li cpu a processor .It Li bus @@ -83,6 +85,32 @@ a network interface everything else .El .Pp +.It Fl s Ar state +specifies a required state or set of states to further restrict the +list of devices. States are specified using the following letters: +.Pp +.Bl -tag -compact -width "! or ~" +.It Li \&! or Li \&~ +at the beginning of a string requests the complement of the specified +states. +.It Li \&? +requests devices with state +.Dv DC_UNKNOWN . +.It Li \&u +requests devices with state +.Dv DC_UNCONFIGURED . +.It Li \&i +requests devices with state +.Dv DC_IDLE . +.It Li \&b +requests devices with state +.Dv DC_BUSY . +.El +.Pp +Multiple +.Fl s +options can be specified, in which case the union of all the requested +states is taken. .It Fl f Ar outfile specifies the name a file where the name of the selected device is written. If no file is specified, the name is written on the standard diff --git a/usr.bin/devmenu/devmenu.c b/usr.bin/devmenu/devmenu.c index e1dc7b42d296..e4e64a6f5bdb 100644 --- a/usr.bin/devmenu/devmenu.c +++ b/usr.bin/devmenu/devmenu.c @@ -36,7 +36,7 @@ #ifndef lint static const char rcsid[] = - "$Id$"; + "$Id: devmenu.c,v 1.1 1995/04/13 21:10:59 wollman Exp $"; #endif #include @@ -54,6 +54,7 @@ static const char rcsid[] = #include "devmenu.h" static enum dc_class interpret_class(char *str); +static int interpret_state(char *str); static void dm_err_exit(int); static int err_writefn(void *cookie, const char *val, int nchars); static void usage(const char *); @@ -68,14 +69,18 @@ main(int argc, char **argv) const char *title = 0, *hfile = 0; char **devnames = 0; int c; + int states = 0; const char *fn = 0; const char *sel = "none"; - while ((c = getopt(argc, argv, "c:t:h:nidf:")) != EOF) { + while ((c = getopt(argc, argv, "c:s:t:h:nidf:")) != EOF) { switch(c) { case 'c': class |= interpret_class(optarg); break; + case 's': + states |= interpret_state(optarg); + break; case 't': title = optarg; break; @@ -118,25 +123,28 @@ main(int argc, char **argv) switch(mode) { case NETIF: - sel = devmenu_netif(title, hfile, devnames); + sel = devmenu_netif(title, hfile, devnames, states); break; case INSTALL: sel = devmenu_common(title, hfile, devnames, "Select an installation device", "No installation devices found", - DC_CLS_DISK | DC_CLS_RDISK | DC_CLS_TAPE); + DC_CLS_DISK | DC_CLS_RDISK | DC_CLS_TAPE, + states); break; case DISK: sel = devmenu_common(title, hfile, devnames, "Select a disk", "No disks found", - DC_CLS_DISK); + DC_CLS_DISK, + states); break; case GENERIC: sel = devmenu_common(title, hfile, devnames, "Select a device", "No devices found", - class); + class, + states); break; } err_set_file(0); @@ -178,6 +186,42 @@ interpret_class(char *str) return rv; } +static int +interpret_state(char *str) +{ + int rv = 0; + int invert = 0; + + if (*str == '!' || *str == '~') { + invert = 1; + str++; + } + + for (; *str; str++) { + switch(*str) { + case 'u': + case 'U': + rv |= 1 << DC_UNCONFIGURED; + break; + case '?': + rv |= 1 << DC_UNKNOWN; + break; + case 'i': + case 'I': + rv |= 1 << DC_IDLE; + break; + case 'b': + case 'B': + rv |= 1 << DC_BUSY; + break; + default: + err(EX_USAGE, "unknown state `%c'", *str); + } + } + + return (invert ? ~rv : rv); +} + static void dm_err_exit(int rval) { @@ -202,5 +246,8 @@ err_writefn(void *cookie, const char *val, int nchars) static void usage(const char *argv0) { - fprintf(stderr, "%s: usage:\n%s foo\n", argv0, argv0); + fprintf(stderr, "%s: usage:\n" + "%s [-c class] [-s state] [-t title] [-h hfile] [-f outfile]" + "[-n] [-i] [-d]\n", argv0, argv0); + } diff --git a/usr.bin/devmenu/devmenu.h b/usr.bin/devmenu/devmenu.h index f5b14a160b3d..2cf77e31aedf 100644 --- a/usr.bin/devmenu/devmenu.h +++ b/usr.bin/devmenu/devmenu.h @@ -26,16 +26,13 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: devmenu.h,v 1.1 1995/04/13 21:11:00 wollman Exp $ */ /* NB: must include sys/devconf.h before this file */ -/* Args are: title, help file, device name list */ -extern const char *devmenu_netif(const char *, const char *, char **); - -/* Args are: title, help file, class mask, name list */ -extern const char *devmenu(const char *, const char *, enum dc_class, char **); +/* Args are: title, help file, device name list, states */ +extern const char *devmenu_netif(const char *, const char *, char **, int); extern char *devmenu_toname(const struct devconf *); @@ -48,7 +45,8 @@ extern struct devconf **devmenu_alldevs(void); /* Frees the array allocated above */ extern void devmenu_freedevs(struct devconf ***); -/* Args are: title, help file, name list, prompt, no-devices message, class */ +/* Args are: title, help file, name list, prompt, no-devices, class, states */ extern const char *devmenu_common(const char *, const char *, char **, - const char *, const char *, enum dc_class); + const char *, const char *, enum dc_class, + int); diff --git a/usr.bin/devmenu/ifmenu.c b/usr.bin/devmenu/ifmenu.c index aecbb7fb0c30..801535b322c0 100644 --- a/usr.bin/devmenu/ifmenu.c +++ b/usr.bin/devmenu/ifmenu.c @@ -42,10 +42,11 @@ * network interfaces might be added as well. */ const char * -devmenu_netif(const char *title, const char *hfile, char **devnames) +devmenu_netif(const char *title, const char *hfile, char **devnames, + int states) { return devmenu_common(title, hfile, devnames, "Select a network interface", "No network interfaces available", - DC_CLS_NETIF); + DC_CLS_NETIF, states); }