Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6.git] / Documentation / connector / ucon.c
index c5092ad..4848db8 100644 (file)
 
 #include <arpa/inet.h>
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
 #include <time.h>
+#include <getopt.h>
 
 #include <linux/connector.h>
 
 #define DEBUG
 #define NETLINK_CONNECTOR      11
 
+/* Hopefully your userspace connector.h matches this kernel */
+#define CN_TEST_IDX            CN_NETLINK_USERS + 3
+#define CN_TEST_VAL            0x456
+
 #ifdef DEBUG
 #define ulog(f, a...) fprintf(stdout, f, ##a)
 #else
@@ -83,6 +89,25 @@ static int netlink_send(int s, struct cn_msg *msg)
        return err;
 }
 
+static void usage(void)
+{
+       printf(
+               "Usage: ucon [options] [output file]\n"
+               "\n"
+               "\t-h\tthis help screen\n"
+               "\t-s\tsend buffers to the test module\n"
+               "\n"
+               "The default behavior of ucon is to subscribe to the test module\n"
+               "and wait for state messages.  Any ones received are dumped to the\n"
+               "specified output file (or stdout).  The test module is assumed to\n"
+               "have an id of {%u.%u}\n"
+               "\n"
+               "If you get no output, then verify the cn_test module id matches\n"
+               "the expected id above.\n"
+               , CN_TEST_IDX, CN_TEST_VAL
+       );
+}
+
 int main(int argc, char *argv[])
 {
        int s;
@@ -94,17 +119,34 @@ int main(int argc, char *argv[])
        FILE *out;
        time_t tm;
        struct pollfd pfd;
+       bool send_msgs = false;
 
-       if (argc < 2)
-               out = stdout;
-       else {
-               out = fopen(argv[1], "a+");
+       while ((s = getopt(argc, argv, "hs")) != -1) {
+               switch (s) {
+               case 's':
+                       send_msgs = true;
+                       break;
+
+               case 'h':
+                       usage();
+                       return 0;
+
+               default:
+                       /* getopt() outputs an error for us */
+                       usage();
+                       return 1;
+               }
+       }
+
+       if (argc != optind) {
+               out = fopen(argv[optind], "a+");
                if (!out) {
                        ulog("Unable to open %s for writing: %s\n",
                                argv[1], strerror(errno));
                        out = stdout;
                }
-       }
+       } else
+               out = stdout;
 
        memset(buf, 0, sizeof(buf));
 
@@ -115,9 +157,11 @@ int main(int argc, char *argv[])
        }
 
        l_local.nl_family = AF_NETLINK;
-       l_local.nl_groups = 0x123; /* bitmask of requested groups */
+       l_local.nl_groups = -1; /* bitmask of requested groups */
        l_local.nl_pid = 0;
 
+       ulog("subscribing to %u.%u\n", CN_TEST_IDX, CN_TEST_VAL);
+
        if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
                perror("bind");
                close(s);
@@ -130,15 +174,15 @@ int main(int argc, char *argv[])
                setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on));
        }
 #endif
-       if (0) {
+       if (send_msgs) {
                int i, j;
 
                memset(buf, 0, sizeof(buf));
 
                data = (struct cn_msg *)buf;
 
-               data->id.idx = 0x123;
-               data->id.val = 0x456;
+               data->id.idx = CN_TEST_IDX;
+               data->id.val = CN_TEST_VAL;
                data->seq = seq++;
                data->ack = 0;
                data->len = 0;