2010-01-22 23:35:36

by Darren Salt

[permalink] [raw]
Subject: [PATCH 1/6] Add "wlan" and "ultrawideband" as aliases for "wifi" and "uwb".

I tend to think "wlan" rather than "wifi"; also, it fits in nicely with "wwan".
Also, these aliases are what the kernel uses.
---
rfkill.8 | 3 ++-
rfkill.c | 4 +++-
2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/rfkill.8 b/rfkill.8
index da06b27..612e366 100644
--- a/rfkill.8
+++ b/rfkill.8
@@ -22,7 +22,8 @@ List the current state of all available rfkill-using devices.
.TP
.BI block " index|type"
Disable the device corresponding to the given index.
-\fItype\fR is one of "all", "wifi", "bluetooth", "uwb", "wimax", "wwan" or "gps".
+\fItype\fR is one of "all", "wifi", "wlan", "bluetooth", "uwb",
+"ultrawideband", "wimax", "wwan" or "gps".
.TP
.BI unblock " index|type"
Enable the device corresponding to the given index. If the device is
diff --git a/rfkill.c b/rfkill.c
index 3f71181..7b44b5a 100644
--- a/rfkill.c
+++ b/rfkill.c
@@ -200,8 +200,10 @@ struct rfkill_type_str {
static struct rfkill_type_str rfkill_type_strings[] = {
{ .type = RFKILL_TYPE_ALL, .name = "all" },
{ .type = RFKILL_TYPE_WLAN, .name = "wifi" },
+ { .type = RFKILL_TYPE_WLAN, .name = "wlan" }, /* alias */
{ .type = RFKILL_TYPE_BLUETOOTH, .name = "bluetooth" },
{ .type = RFKILL_TYPE_UWB, .name = "uwb" },
+ { .type = RFKILL_TYPE_UWB, .name = "ultrawideband" }, /* alias */
{ .type = RFKILL_TYPE_WIMAX, .name = "wimax" },
{ .type = RFKILL_TYPE_WWAN, .name = "wwan" },
{ .type = RFKILL_TYPE_GPS, .name = "gps" },
@@ -222,7 +224,7 @@ static enum rfkill_type rfkill_str_to_type(char *s)

static const char *argv0;

-#define BLOCK_PARAMS "{<idx>,all,wifi,bluetooth,uwb,wimax,wwan,gps}"
+#define BLOCK_PARAMS "{<idx>,all,wifi,wlan,bluetooth,uwb,ultrawideband,wimax,wwan,gps}"

static void usage(void)
{
--
1.6.5



2010-01-22 23:35:36

by Darren Salt

[permalink] [raw]
Subject: [PATCH 5/6] Refactor rfkill index/type lookup: move it below rfkill_block.

---
rfkill.c | 130 +++++++++++++++++++++++++++++++++++---------------------------
1 files changed, 73 insertions(+), 57 deletions(-)

diff --git a/rfkill.c b/rfkill.c
index 4cf507a..998728e 100644
--- a/rfkill.c
+++ b/rfkill.c
@@ -118,6 +118,60 @@ static const char *type2string(enum rfkill_type type)
return NULL;
}

+struct rfkill_type_str {
+ enum rfkill_type type;
+ const char *name;
+};
+static const struct rfkill_type_str rfkill_type_strings[] = {
+ { .type = RFKILL_TYPE_ALL, .name = "all" },
+ { .type = RFKILL_TYPE_WLAN, .name = "wifi" },
+ { .type = RFKILL_TYPE_WLAN, .name = "wlan" }, /* alias */
+ { .type = RFKILL_TYPE_BLUETOOTH, .name = "bluetooth" },
+ { .type = RFKILL_TYPE_UWB, .name = "uwb" },
+ { .type = RFKILL_TYPE_UWB, .name = "ultrawideband" }, /* alias */
+ { .type = RFKILL_TYPE_WIMAX, .name = "wimax" },
+ { .type = RFKILL_TYPE_WWAN, .name = "wwan" },
+ { .type = RFKILL_TYPE_GPS, .name = "gps" },
+ { .type = RFKILL_TYPE_FM, .name = "fm" },
+ { .name = NULL }
+};
+
+struct rfkill_id {
+ union {
+ enum rfkill_type type;
+ __u32 index;
+ };
+ enum {
+ RFKILL_IS_INVALID,
+ RFKILL_IS_TYPE,
+ RFKILL_IS_INDEX,
+ } result;
+};
+
+static struct rfkill_id rfkill_id_to_type(const char *s)
+{
+ const struct rfkill_type_str *p;
+ struct rfkill_id ret;
+
+ if (islower(*s)) {
+ for (p = rfkill_type_strings; p->name != NULL; p++) {
+ if ((strlen(s) == strlen(p->name)) && (!strcmp(s,p->name))) {
+ ret.type = p->type;
+ ret.result = RFKILL_IS_TYPE;
+ return ret;
+ }
+ }
+ } else if (isdigit(*s)) {
+ /* assume a numeric character implies an index. */
+ ret.index = atoi(s);
+ ret.result = RFKILL_IS_INDEX;
+ return ret;
+ }
+
+ ret.result = RFKILL_IS_INVALID;
+ return ret;
+}
+
static int rfkill_list(void)
{
struct rfkill_event event;
@@ -166,12 +220,19 @@ static int rfkill_list(void)
return 0;
}

-static int rfkill_block(bool all, __u32 idx, __u8 block, __u8 type)
+static int rfkill_block(__u8 block, const char *param)
{
+ struct rfkill_id id;
struct rfkill_event event;
ssize_t len;
int fd;

+ id = rfkill_id_to_type(param);
+ if (id.result == RFKILL_IS_INVALID) {
+ fprintf(stderr, "Bogus %s argument '%s'.\n", block ? "block" : "unblock", param);
+ return 2;
+ }
+
fd = open("/dev/rfkill", O_RDWR);
if (fd < 0) {
perror("Can't open RFKILL control device");
@@ -179,12 +240,16 @@ static int rfkill_block(bool all, __u32 idx, __u8 block, __u8 type)
}

memset(&event, 0, sizeof(event));
- if (!all) {
- event.idx = idx;
- event.op = RFKILL_OP_CHANGE;
- } else {
+ switch (id.result) {
+ case RFKILL_IS_TYPE:
event.op = RFKILL_OP_CHANGE_ALL;
- event.type = type;
+ event.type = id.type;
+ break;
+ case RFKILL_IS_INDEX:
+ event.op = RFKILL_OP_CHANGE;
+ event.idx = id.index;
+ break;
+ case RFKILL_IS_INVALID:; /* must be last */
}
event.soft = block;

@@ -196,35 +261,6 @@ static int rfkill_block(bool all, __u32 idx, __u8 block, __u8 type)
return 0;
}

-struct rfkill_type_str {
- enum rfkill_type type;
- const char *name;
-};
-static const struct rfkill_type_str rfkill_type_strings[] = {
- { .type = RFKILL_TYPE_ALL, .name = "all" },
- { .type = RFKILL_TYPE_WLAN, .name = "wifi" },
- { .type = RFKILL_TYPE_WLAN, .name = "wlan" }, /* alias */
- { .type = RFKILL_TYPE_BLUETOOTH, .name = "bluetooth" },
- { .type = RFKILL_TYPE_UWB, .name = "uwb" },
- { .type = RFKILL_TYPE_UWB, .name = "ultrawideband" }, /* alias */
- { .type = RFKILL_TYPE_WIMAX, .name = "wimax" },
- { .type = RFKILL_TYPE_WWAN, .name = "wwan" },
- { .type = RFKILL_TYPE_GPS, .name = "gps" },
- { .type = RFKILL_TYPE_FM, .name = "fm" },
- { .name = NULL }
-};
-
-static enum rfkill_type rfkill_str_to_type(const char *s)
-{
- const struct rfkill_type_str *p;
-
- for (p = rfkill_type_strings; p->name != NULL; p++) {
- if ((strlen(s) == strlen(p->name)) && (!strcmp(s,p->name)))
- return p->type;
- }
- return NUM_RFKILL_TYPES;
-}
-
static const char *argv0;

static void usage(void)
@@ -247,26 +283,6 @@ static void version(void)
printf("rfkill %s\n", rfkill_version);
}

-static int do_block_unblock(__u8 block, const char *param)
-{
- enum rfkill_type t;
- __u32 idx;
-
- if (islower(*param)) {
- /* assume alphabetic characters imply a wireless type name */
- t = rfkill_str_to_type(param);
- if (t < NUM_RFKILL_TYPES)
- return rfkill_block(true, 0, block, t);
- } else if (isdigit(*param)) {
- /* assume a numeric character implies an index. */
- idx = atoi(param);
- return rfkill_block(false, idx, block, 0);
- }
-
- fprintf(stderr,"Bogus %sblock argument '%s'.\n",block?"":"un",param);
- exit(1);
-}
-
int main(int argc, char **argv)
{
int ret = 0;
@@ -292,11 +308,11 @@ int main(int argc, char **argv)
} else if (strcmp(*argv, "block") == 0 && argc > 1) {
argc--;
argv++;
- ret = do_block_unblock(1,*argv);
+ ret = rfkill_block(1,*argv);
} else if (strcmp(*argv, "unblock") == 0 && argc > 1) {
argc--;
argv++;
- ret = do_block_unblock(0,*argv);
+ ret = rfkill_block(0,*argv);
} else {
usage();
return 1;
--
1.6.5


2010-01-22 23:35:36

by Darren Salt

[permalink] [raw]
Subject: [PATCH 4/6] Return error codes instead of exiting.

---
rfkill.c | 32 ++++++++++++++++----------------
1 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/rfkill.c b/rfkill.c
index 8c0aea6..4cf507a 100644
--- a/rfkill.c
+++ b/rfkill.c
@@ -118,7 +118,7 @@ static const char *type2string(enum rfkill_type type)
return NULL;
}

-static void rfkill_list(void)
+static int rfkill_list(void)
{
struct rfkill_event event;
const char *name;
@@ -128,12 +128,13 @@ static void rfkill_list(void)
fd = open("/dev/rfkill", O_RDONLY);
if (fd < 0) {
perror("Can't open RFKILL control device");
- return;
+ return 1;
}

if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
perror("Can't set RFKILL control device to non-blocking");
close(fd);
+ return 1;
}

while (1) {
@@ -162,9 +163,10 @@ static void rfkill_list(void)
}

close(fd);
+ return 0;
}

-static void rfkill_block(bool all, __u32 idx, __u8 block, __u8 type)
+static int rfkill_block(bool all, __u32 idx, __u8 block, __u8 type)
{
struct rfkill_event event;
ssize_t len;
@@ -173,7 +175,7 @@ static void rfkill_block(bool all, __u32 idx, __u8 block, __u8 type)
fd = open("/dev/rfkill", O_RDWR);
if (fd < 0) {
perror("Can't open RFKILL control device");
- return;
+ return 1;
}

memset(&event, 0, sizeof(event));
@@ -191,6 +193,7 @@ static void rfkill_block(bool all, __u32 idx, __u8 block, __u8 type)
perror("Failed to change RFKILL state");

close(fd);
+ return 0;
}

struct rfkill_type_str {
@@ -244,7 +247,7 @@ static void version(void)
printf("rfkill %s\n", rfkill_version);
}

-static void do_block_unblock(__u8 block, const char *param)
+static int do_block_unblock(__u8 block, const char *param)
{
enum rfkill_type t;
__u32 idx;
@@ -253,24 +256,21 @@ static void do_block_unblock(__u8 block, const char *param)
/* assume alphabetic characters imply a wireless type name */
t = rfkill_str_to_type(param);
if (t < NUM_RFKILL_TYPES)
- rfkill_block(true, 0, block, t);
- else
- goto err;
+ return rfkill_block(true, 0, block, t);
} else if (isdigit(*param)) {
/* assume a numeric character implies an index. */
idx = atoi(param);
- rfkill_block(false, idx, block, 0);
- } else
- goto err;
+ return rfkill_block(false, idx, block, 0);
+ }

- return;
-err:
fprintf(stderr,"Bogus %sblock argument '%s'.\n",block?"":"un",param);
exit(1);
}

int main(int argc, char **argv)
{
+ int ret = 0;
+
/* strip off self */
argc--;
argv0 = *argv++;
@@ -292,15 +292,15 @@ int main(int argc, char **argv)
} else if (strcmp(*argv, "block") == 0 && argc > 1) {
argc--;
argv++;
- do_block_unblock(1,*argv);
+ ret = do_block_unblock(1,*argv);
} else if (strcmp(*argv, "unblock") == 0 && argc > 1) {
argc--;
argv++;
- do_block_unblock(0,*argv);
+ ret = do_block_unblock(0,*argv);
} else {
usage();
return 1;
}

- return 0;
+ return ret;
}
--
1.6.5


2010-01-22 23:35:36

by Darren Salt

[permalink] [raw]
Subject: [PATCH 6/6] Add filtering to "rfkill list".

---
rfkill.c | 34 +++++++++++++++++++++++++++++++---
1 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/rfkill.c b/rfkill.c
index 998728e..8fa4c6a 100644
--- a/rfkill.c
+++ b/rfkill.c
@@ -172,13 +172,25 @@ static struct rfkill_id rfkill_id_to_type(const char *s)
return ret;
}

-static int rfkill_list(void)
+static int rfkill_list(const char *param)
{
+ struct rfkill_id id = { .result = RFKILL_IS_INVALID };
struct rfkill_event event;
const char *name;
ssize_t len;
int fd;

+ if (param) {
+ id = rfkill_id_to_type(param);
+ if (id.result == RFKILL_IS_INVALID) {
+ fprintf(stderr, "Bogus %s argument '%s'.\n", "list", param);
+ return 2;
+ }
+ /* don't filter "all" */
+ if (id.result == RFKILL_IS_TYPE && id.type == RFKILL_TYPE_ALL)
+ id.result = RFKILL_IS_INVALID;
+ }
+
fd = open("/dev/rfkill", O_RDONLY);
if (fd < 0) {
perror("Can't open RFKILL control device");
@@ -208,6 +220,20 @@ static int rfkill_list(void)
if (event.op != RFKILL_OP_ADD)
continue;

+ /* filter out unwanted results */
+ switch (id.result)
+ {
+ case RFKILL_IS_TYPE:
+ if (event.type != id.type)
+ continue;
+ break;
+ case RFKILL_IS_INDEX:
+ if (event.idx != id.index)
+ continue;
+ break;
+ case RFKILL_IS_INVALID:; /* must be last */
+ }
+
name = get_name(event.idx);

printf("%u: %s: %s\n", event.idx, name,
@@ -271,7 +297,7 @@ static void usage(void)
fprintf(stderr, "Commands:\n");
fprintf(stderr, "\thelp\n");
fprintf(stderr, "\tevent\n");
- fprintf(stderr, "\tlist\n");
+ fprintf(stderr, "\tlist [IDENTIFIER]\n");
fprintf(stderr, "\tblock IDENTIFIER\n");
fprintf(stderr, "\tunblock IDENTIFIER\n");
fprintf(stderr, "where IDENTIFIER is the index no. of an rfkill switch or one of:\n");
@@ -304,7 +330,9 @@ int main(int argc, char **argv)
if (strcmp(*argv, "event") == 0) {
rfkill_event();
} else if (strcmp(*argv, "list") == 0) {
- rfkill_list();
+ argc--;
+ argv++;
+ rfkill_list(*argv); /* NULL is acceptable */
} else if (strcmp(*argv, "block") == 0 && argc > 1) {
argc--;
argv++;
--
1.6.5


2010-01-22 23:35:36

by Darren Salt

[permalink] [raw]
Subject: [PATCH 3/6] Constification.

---
rfkill.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/rfkill.c b/rfkill.c
index 3cb2605..8c0aea6 100644
--- a/rfkill.c
+++ b/rfkill.c
@@ -195,9 +195,9 @@ static void rfkill_block(bool all, __u32 idx, __u8 block, __u8 type)

struct rfkill_type_str {
enum rfkill_type type;
- char *name;
+ const char *name;
};
-static struct rfkill_type_str rfkill_type_strings[] = {
+static const struct rfkill_type_str rfkill_type_strings[] = {
{ .type = RFKILL_TYPE_ALL, .name = "all" },
{ .type = RFKILL_TYPE_WLAN, .name = "wifi" },
{ .type = RFKILL_TYPE_WLAN, .name = "wlan" }, /* alias */
@@ -211,9 +211,9 @@ static struct rfkill_type_str rfkill_type_strings[] = {
{ .name = NULL }
};

-static enum rfkill_type rfkill_str_to_type(char *s)
+static enum rfkill_type rfkill_str_to_type(const char *s)
{
- struct rfkill_type_str *p;
+ const struct rfkill_type_str *p;

for (p = rfkill_type_strings; p->name != NULL; p++) {
if ((strlen(s) == strlen(p->name)) && (!strcmp(s,p->name)))
@@ -244,7 +244,7 @@ static void version(void)
printf("rfkill %s\n", rfkill_version);
}

-static void do_block_unblock(__u8 block, char *param)
+static void do_block_unblock(__u8 block, const char *param)
{
enum rfkill_type t;
__u32 idx;
--
1.6.5


2010-01-22 23:35:36

by Darren Salt

[permalink] [raw]
Subject: [PATCH 2/6] Rearrange the help text for block & unblock.

---
rfkill.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/rfkill.c b/rfkill.c
index 7b44b5a..3cb2605 100644
--- a/rfkill.c
+++ b/rfkill.c
@@ -224,8 +224,6 @@ static enum rfkill_type rfkill_str_to_type(char *s)

static const char *argv0;

-#define BLOCK_PARAMS "{<idx>,all,wifi,wlan,bluetooth,uwb,ultrawideband,wimax,wwan,gps}"
-
static void usage(void)
{
fprintf(stderr, "Usage:\t%s [options] command\n", argv0);
@@ -235,8 +233,10 @@ static void usage(void)
fprintf(stderr, "\thelp\n");
fprintf(stderr, "\tevent\n");
fprintf(stderr, "\tlist\n");
- fprintf(stderr, "\tblock "BLOCK_PARAMS"\n");
- fprintf(stderr, "\tunblock "BLOCK_PARAMS"\n");
+ fprintf(stderr, "\tblock IDENTIFIER\n");
+ fprintf(stderr, "\tunblock IDENTIFIER\n");
+ fprintf(stderr, "where IDENTIFIER is the index no. of an rfkill switch or one of:\n");
+ fprintf(stderr, "\t<idx> all wifi wlan bluetooth uwb ultrawideband wimax wwan gps\n");
}

static void version(void)
--
1.6.5