changeset 1344:788c6c097fa2 draft

Cleanup pass on rfkill.
author Rob Landley <rob@landley.net>
date Mon, 09 Jun 2014 07:07:33 -0500
parents 2538fa09b1b1
children b7598d21ca10
files toys/pending/rfkill.c
diffstat 1 files changed, 51 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/toys/pending/rfkill.c	Mon Jun 09 05:53:43 2014 -0500
+++ b/toys/pending/rfkill.c	Mon Jun 09 07:07:33 2014 -0500
@@ -11,97 +11,91 @@
   bool "rfkill"
   default n
   help
-    Usage: rfkill COMMAND
+    Usage: rfkill COMMAND [DEVICE]
 
     Enable/disable wireless devices.
 
     Commands:
-    list [IDENTIFIER] List current state
-    block IDENTIFIER Disable device
-    unblock IDENTIFIER Enable device
+    list [DEVICE]   List current state
+    block DEVICE    Disable device
+    unblock DEVICE  Enable device
 
-    where IDENTIFIER is the index no. of an rfkill switch or one of:
-    <idx> all, wlan(wifi), bluetooth, uwb(ultrawideband), wimax, wwan, gps, fm.
+    DEVICE is an index number, or one of:
+    all, wlan(wifi), bluetooth, uwb(ultrawideband), wimax, wwan, gps, fm.
 */
+
 #define FOR_rfkill
 #include "toys.h"
 #include <linux/rfkill.h>
 
-struct arglist {
-  char *name;
-  int idx;
-};
-
-static int getidx(char ***argv, struct arglist *list)
-{
-  struct arglist *alist;
-
-  if (!**argv) return -1;
-  for (alist = list; alist->name; alist++)
-    if (!strcmp(**argv, alist->name)) {
-      *argv += 1;
-      return alist->idx;
-    }
-  return -1;
-}
-
 void rfkill_main(void)
 {
   struct rfkill_event rfevent;
   int fd, tvar, idx = -1, tid = RFKILL_TYPE_ALL;
   char **optargs = toys.optargs;
-  struct arglist cmds[] = {{"list", 0}, {"block", 1},
-                          {"unblock", 2}, {NULL, -1}};
 
-  if (((tvar = getidx(&optargs, cmds)) < 0) || ((tvar) && !*optargs)) {
-    toys.exithelp = 1;
-    (tvar < 0) ? error_exit("cmd missmatch")
-            : error_exit("%s idx missing", *toys.optargs);
+  // Parse command line options
+  for (tvar = 0; tvar < 3; tvar++)
+    if (!strcmp((char *[]){"list", "block", "unblock"}[tvar], *optargs)) break;
+  if (tvar == 3) error_exit("unknown cmd '%s'", *optargs);
+  if (tvar) {
+    int i;
+    struct arglist {
+      char *name;
+      int idx;
+    } rftypes[] = {{"all", RFKILL_TYPE_ALL}, {"wifi", RFKILL_TYPE_WLAN},
+      {"wlan", RFKILL_TYPE_WLAN}, {"bluetooth", RFKILL_TYPE_BLUETOOTH},
+      {"uwb", RFKILL_TYPE_UWB}, {"ultrawideband", RFKILL_TYPE_UWB},
+      {"wimax", RFKILL_TYPE_WIMAX}, {"wwan", RFKILL_TYPE_WWAN},
+      {"gps", RFKILL_TYPE_GPS}, {"fm", 7}}; // RFKILL_TYPE_FM = 7
+
+    if (!*++optargs) error_exit("'%s' needs IDENTIFIER");
+    for (i = 0; i < ARRAY_LEN(rftypes); i++)
+      if (!strcmp(rftypes[i].name, *optargs)) break;
+    if (i == ARRAY_LEN(rftypes)) idx = atolx_range(*optargs, 0, INT_MAX);
+    else tid = rftypes[i].idx;
   }
-  if (*optargs) {
-    struct arglist rftypes[] = {{"all", RFKILL_TYPE_ALL},
-      {"wifi", RFKILL_TYPE_WLAN}, {"wlan", RFKILL_TYPE_WLAN},
-      {"bluetooth", RFKILL_TYPE_BLUETOOTH}, {"uwb", RFKILL_TYPE_UWB},
-      {"ultrawideband", RFKILL_TYPE_UWB}, {"wimax", RFKILL_TYPE_WIMAX},
-      {"wwan", RFKILL_TYPE_WWAN}, {"gps", RFKILL_TYPE_GPS}, 
-      {"fm", 7}, {NULL, -1}}; // RFKILL_TYPE_FM = 7
 
-    if ((tid = getidx(&optargs, rftypes)) == -1)
-      idx = atolx_range(*optargs, 0, INT_MAX);
-  }
-  fd = xcreate("/dev/rfkill", (tvar ? O_RDWR : O_RDONLY)|O_NONBLOCK, 0600);
+  // Perform requested action
+  fd = xopen("/dev/rfkill", (tvar ? O_RDWR : O_RDONLY)|O_NONBLOCK);
   if (tvar) {
+    // block/unblock
     memset(&rfevent, 0, sizeof(rfevent));
-    rfevent.soft = (tvar & 1);
-    if (tid != -1) {
+    rfevent.soft = tvar == 1;
+    if (idx >= 0) {
+      rfevent.idx = idx;
+      rfevent.op = RFKILL_OP_CHANGE;
+    } else {
       rfevent.type = tid;
       rfevent.op = RFKILL_OP_CHANGE_ALL;
-    } else if (idx >= 0) {
-      rfevent.idx = idx;
-      rfevent.op = RFKILL_OP_CHANGE;
     }
     xwrite(fd, &rfevent, sizeof(rfevent));
-  } else { // show list.
+  } else {
+    // show list.
     while (sizeof(rfevent) == readall(fd, &rfevent, sizeof(rfevent))) {
-      char *line = NULL, *name = NULL, *type = NULL;
+      char *line, *name = 0, *type = 0;
 
-      // filter of list items.
-      if (((tid > 0) && (tid != rfevent.type)) 
-          || ((idx != -1) && (idx != rfevent.idx))) continue;
+      // filter list items
+      if ((tid > 0 && tid != rfevent.type) || (idx != -1 && idx != rfevent.idx))
+        continue;
+
       sprintf(toybuf, "/sys/class/rfkill/rfkill%u/uevent", rfevent.idx);
       tvar = xopen(toybuf, O_RDONLY);
       while ((line = get_line(tvar))) {
-        if (!strncmp(line, "RFKILL_NAME", strlen("RFKILL_NAME"))) 
-          name = xstrdup(strchr(line, '=')+1);
-        else if (!strncmp(line, "RFKILL_TYPE", strlen("RFKILL_TYPE")))
-          type = xstrdup(strchr(line, '=')+1);
+        char *s = line;
+
+        if (strstart(&s, "RFKILL_NAME=")) name = xstrdup(s);
+        else if (strstart(&s, "RFKILL_TYPE=")) type = xstrdup(s);
+
         free(line);
       }
+      xclose(tvar);
+
       xprintf("%u: %s: %s\n", rfevent.idx, name, type);
       xprintf("\tSoft blocked: %s\n", rfevent.soft ? "yes" : "no");
       xprintf("\tHard blocked: %s\n", rfevent.hard ? "yes" : "no");
-      xclose(tvar);
-      free(name), free(type);
+      free(name);
+      free(type);
     }
   }
   xclose(fd);