Merge branch 'crypt' into next
authorAndre Noll <maan@systemlinux.org>
Sat, 4 Jul 2009 14:25:20 +0000 (16:25 +0200)
committerAndre Noll <maan@systemlinux.org>
Sat, 4 Jul 2009 14:25:20 +0000 (16:25 +0200)
NEWS
acl.c
audiod_command.c
command.c
grab_client.c
net.c
net.h
para.h
send_common.c
stat.c

diff --git a/NEWS b/NEWS
index 4d775ec..dff8208 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,11 +6,13 @@ NEWS
 -------------------------------------------------
 
        - the new oss writer (supported on *BSD and Linux)
+       - support for netmask subsets (Gerrit Renker)
        - the new prebuffer filter
        - improved signal handling
        - variable fec output buffer size
        - --log_color actually works
        - new ls option: -d (print dates as seconds after the epoch)
+       - update to gengetopt 2.22.2
 
 -----------------------------------------
 0.3.4 (2009-05-07) "elliptic inheritance"
diff --git a/acl.c b/acl.c
index 14edcf7..ffcd168 100644 (file)
--- a/acl.c
+++ b/acl.c
@@ -90,13 +90,17 @@ static void acl_add_entry(struct list_head *acl, char *addr, int netmask)
  * \param addr The address to delete.
  * \param netmask The netmask of the entry to be removed from the list.
  */
-static void acl_del_entry(struct list_head *acl, char *addr, int netmask)
+static void acl_del_entry(struct list_head *acl, char *addr, unsigned netmask)
 {
        struct access_info *ai, *tmp;
+       struct in_addr to_delete;
+
+       inet_pton(AF_INET, addr, &to_delete);
 
        list_for_each_entry_safe(ai, tmp, acl, node) {
-               if (!strcmp(addr, inet_ntoa(ai->addr)) &&
-                               ai->netmask == netmask) {
+
+               if (v4_addr_match(to_delete.s_addr, ai->addr.s_addr,
+                                       PARA_MIN(netmask, ai->netmask))) {
                        PARA_NOTICE_LOG("removing %s/%i from access list\n",
                                        addr, ai->netmask);
                        list_del(&ai->node);
@@ -136,30 +140,16 @@ char *acl_get_contents(struct list_head *acl)
  */
 void acl_init(struct list_head *acl, char * const *acl_info, int num)
 {
-       int i;
+       char    addr[16];
+       int     mask, i;
 
        INIT_LIST_HEAD(acl);
-       for (i = 0; i < num; i++) {
-               char *arg = para_strdup(acl_info[i]);
-               char *p = strchr(arg, '/');
-               int netmask;
-
-               if (!p)
-                       goto err;
-               *p = '\0';
-               if (!is_valid_ipv4_address(arg))
-                       goto err;
-               netmask = atoi(++p);
-               if (netmask < 0 || netmask > 32)
-                       goto err;
-               acl_add_entry(acl, arg, netmask);
-               goto success;
-err:
-               PARA_CRIT_LOG("syntax error: %s\n", acl_info[i]);
-success:
-               free(arg);
-               continue;
-       }
+       for (i = 0; i < num; i++)
+               if (parse_cidr(acl_info[i], addr, sizeof(addr), &mask) == NULL)
+                       PARA_CRIT_LOG("ACL syntax error: %s, ignoring\n",
+                                     acl_info[i]);
+               else
+                       acl_add_entry(acl, addr, mask);
 }
 
 /**
index 3467dbe..ca1bff5 100644 (file)
@@ -166,23 +166,24 @@ int com_kill(int fd, int argc, char **argv)
        return ret;
 }
 
-int com_stat(int fd, __a_unused int argc, __a_unused char **argv)
+int com_stat(int fd, int argc, char **argv)
 {
        int i, ret;
        char *buf = NULL;
-       long unsigned mask = ~0LU;
+       uint64_t mask = 0;
+       const uint64_t one = 1;
 
        if (argc > 1) {
-               mask = 0;
                for (i = 1; i < argc; i++) {
                        ret = stat_item_valid(argv[i]);
                        if (ret < 0)
                                return ret;
-                       mask |= (1 << ret);
+                       mask |= (one << ret);
                }
-       }
-       PARA_INFO_LOG("mask: 0x%lx\n", mask);
-       if (mask & (1 << SI_PLAY_TIME)) {
+       } else
+               mask--; /* set all bits */
+       PARA_INFO_LOG("mask: 0x%llx\n", (long long unsigned)mask);
+       if (mask & (one << SI_PLAY_TIME)) {
                int slot_num = get_play_time_slot_num();
                char *ts = get_time_string(slot_num);
                if (ts) {
@@ -192,7 +193,7 @@ int com_stat(int fd, __a_unused int argc, __a_unused char **argv)
                        free(ts);
                }
        }
-       if (mask & (1 << SI_AUDIOD_UPTIME)) {
+       if (mask & (one << SI_AUDIOD_UPTIME)) {
                char *tmp, *us = uptime_str();
                tmp = make_message("%s: %s\n",
                        status_item_list[SI_AUDIOD_UPTIME], us);
@@ -202,14 +203,14 @@ int com_stat(int fd, __a_unused int argc, __a_unused char **argv)
                        goto out;
                free(tmp);
        }
-       if (mask & (1 << SI_AUDIOD_STATUS)) {
+       if (mask & (one << SI_AUDIOD_STATUS)) {
                char *s = audiod_status_string();
                ret = client_write(fd, s);
                if (ret < 0)
                        goto out;
                free(s);
        }
-       if (mask & (1 << SI_DECODER_FLAGS)) {
+       if (mask & (one << SI_DECODER_FLAGS)) {
                char *df = decoder_flags();
                ret = client_write(fd, df);
                if (ret < 0)
@@ -218,7 +219,7 @@ int com_stat(int fd, __a_unused int argc, __a_unused char **argv)
        }
        FOR_EACH_STATUS_ITEM(i) {
                char *tmp, *v;
-               if (!((1 << i) & mask))
+               if (!((one << i) & mask))
                        continue;
                v = stat_item_values[i];
                tmp = make_message("%s%s%s", buf? buf: "",
index a14fff8..fc5b5ca 100644 (file)
--- a/command.c
+++ b/command.c
@@ -183,17 +183,9 @@ static int check_sender_args(int argc, char * const * argv, struct sender_comman
                break;
        case SENDER_DENY:
        case SENDER_ALLOW:
-               if (argc != 4 && argc != 5)
+               if (argc != 4 || parse_cidr(argv[3], scd->host,
+                               sizeof(scd->host), &scd->netmask) == NULL)
                        return -E_COMMAND_SYNTAX;
-               if (!is_valid_ipv4_address(argv[3]))
-                       return -E_COMMAND_SYNTAX;
-               scd->netmask = 32;
-               if (argc == 5) {
-                       scd->netmask = atoi(argv[4]);
-                       if (scd->netmask < 0 || scd->netmask > 32)
-                               return -E_COMMAND_SYNTAX;
-               }
-               strncpy(scd->host, argv[3], sizeof(scd->host));
                break;
        case SENDER_ADD:
        case SENDER_DELETE:
index ccfdb0c..9b4ef69 100644 (file)
@@ -82,7 +82,7 @@ static int check_gc_args(struct grab_client *gc)
 {
        int i;
        struct grab_client_args_info *c = gc->conf;
-       char **mv = grab_client_cmdline_parser_mode_values;
+       const char **mv = grab_client_cmdline_parser_mode_values;
 
        PARA_INFO_LOG("filter_num: %d\n", c->filter_num_arg);
        for (i = 0; mv[i]; i++)
diff --git a/net.c b/net.c
index f10afb7..b3588f6 100644 (file)
--- a/net.c
+++ b/net.c
 #include "string.h"
 #include "fd.h"
 
+/**
+ * Parse and validate IPv4 address/netmask string.
+ *
+ * \param cidr   Address in CIDR notation
+ * \param addr   Copy of the IPv4 address part of \a cidr
+ * \param addrlen Size of \a addr in bytes
+ * \param netmask Value of the netmask part in \a cidr or the
+ *               default of 32 if not specified.
+ *
+ * \return Pointer to \a addr if succesful, NULL on error.
+ * \sa RFC 4632
+ */
+char *parse_cidr(const char *cidr,
+                char    *addr, ssize_t addrlen,
+                int32_t *netmask)
+{
+       const char *o = cidr;
+       char *c = addr, *end = c + (addrlen - 1);
+
+       *netmask = 0x20;
+
+       if (cidr == NULL || addrlen < 1)
+               goto failed;
+
+       for (o = cidr; (*c = *o == '/'? '\0' : *o); c++, o++)
+               if (c == end)
+                       goto failed;
+
+       if (*o == '/')
+               if (para_atoi32(++o, netmask) < 0 ||
+                   *netmask < 0 || *netmask > 0x20)
+                       goto failed;
+
+       if (is_valid_ipv4_address(addr))
+               return addr;
+failed:
+       *addr = '\0';
+       return NULL;
+}
+
+
 /**
  * Match string as a candidate IPv4 address.
  *
diff --git a/net.h b/net.h
index b85403f..1541258 100644 (file)
--- a/net.h
+++ b/net.h
@@ -29,6 +29,8 @@
 /**
  * Functions to parse and validate (parts of) URLs.
  */
+extern char *parse_cidr(const char *cidr,
+                       char *addr, ssize_t addrlen, int32_t *netmask);
 extern char *parse_url(const char *url,
                       char *host, ssize_t hostlen, int32_t *port);
 /**
diff --git a/para.h b/para.h
index 112d5fe..d49d722 100644 (file)
--- a/para.h
+++ b/para.h
@@ -184,7 +184,7 @@ extern const char *status_item_list[];
 int stat_item_valid(const char *item);
 int stat_line_valid(const char *);
 void stat_client_write(const char *msg, int itemnum);
-int stat_client_add(int fd, long unsigned mask);
+int stat_client_add(int fd, uint64_t mask);
 
 __printf_2_3 void para_log(int, const char*, ...);
 
index b816007..200e59a 100644 (file)
@@ -389,8 +389,9 @@ char *generic_sender_help(void)
 {
        return make_message(
                "usage: {on|off}\n"
-               "usage: {allow|deny} IP mask\n"
-               "example: allow 127.0.0.1 32\n"
+               "usage: {allow|deny} IP[/netmask]\n"
+               "       where mask defaults to 32\n"
+               "example: allow 192.168.0.1/24\n"
        );
 }
 
diff --git a/stat.c b/stat.c
index 4ba1b0e..0306cba 100644 (file)
--- a/stat.c
+++ b/stat.c
@@ -35,7 +35,7 @@ struct stat_client {
        /** The stat client's file descriptor. */
        int fd;
        /** Bitmask of those status items the client is interested in. */
-       long unsigned item_mask;
+       uint64_t item_mask;
        /** Its entry in the list of stat clients. */
        struct list_head node;
 };
@@ -68,7 +68,7 @@ static void dump_stat_client_list(void)
  * \return Positive value on success, or -E_TOO_MANY_CLIENTS if
  * the number of connected clients exceeds #MAX_STAT_CLIENTS.
  */
-int stat_client_add(int fd, long unsigned mask)
+int stat_client_add(int fd, uint64_t mask)
 {
        struct stat_client *new_client;
 
@@ -103,13 +103,14 @@ void stat_client_write(const char *msg, int itemnum)
 {
        struct stat_client *sc, *tmp;
        size_t len = strlen(msg);
+       const uint64_t one = 1;
 
        if (!initialized || !len)
                return;
        list_for_each_entry_safe(sc, tmp, &client_list, node) {
                int fd = sc->fd, ret;
 
-               if (!((1 << itemnum) & sc->item_mask))
+               if (!((one << itemnum) & sc->item_mask))
                        continue;
                if (write_ok(fd) > 0) {
                        ret = write(fd, msg, len);