Merge config aliasing bug fix.
authorRichard Kettlewell <rjk@greenend.org.uk>
Sat, 14 Mar 2009 19:03:08 +0000 (19:03 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sat, 14 Mar 2009 19:03:08 +0000 (19:03 +0000)
1  2 
lib/configuration.c

diff --combined lib/configuration.c
@@@ -489,18 -489,6 +489,18 @@@ static int set_rights(const struct conf
    return 0;
  }
  
 +static int set_netaddress(const struct config_state *cs,
 +                        const struct conf *whoami,
 +                        int nvec, char **vec) {
 +  struct netaddress *na = ADDRESS(cs->config, struct netaddress);
 +
 +  if(netaddress_parse(na, nvec, vec)) {
 +    error(0, "%s:%d: invalid network address", cs->path, cs->line);
 +    return -1;
 +  }
 +  return 0;
 +}
 +
  /* free functions */
  
  static void free_none(struct config attribute((unused)) *c,
  static void free_string(struct config *c,
                        const struct conf *whoami) {
    xfree(VALUE(c, char *));
+   VALUE(c, char *) = 0;
  }
  
  static void free_stringlist(struct config *c,
@@@ -584,13 -573,6 +585,13 @@@ static void free_transformlist(struct c
    xfree(tl->t);
  }
  
 +static void free_netaddress(struct config *c,
 +                          const struct conf *whoami) {
 +  struct netaddress *na = ADDRESS(c, struct netaddress);
 +
 +  xfree(na->address);
 +}
 +
  /* configuration types */
  
  static const struct conftype
    type_restrict = { set_restrict, free_none },
    type_namepart = { set_namepart, free_namepartlist },
    type_transform = { set_transform, free_transformlist },
 +  type_netaddress = { set_netaddress, free_netaddress },
    type_rights = { set_rights, free_none };
  
  /* specific validation routine */
@@@ -833,6 -814,45 +834,6 @@@ static int validate_alias(const struct 
    return 0;
  }
  
 -static int validate_addrport(const struct config_state attribute((unused)) *cs,
 -                           int nvec,
 -                           char attribute((unused)) **vec) {
 -  switch(nvec) {
 -  case 0:
 -    error(0, "%s:%d: missing address",
 -        cs->path, cs->line);
 -    return -1;
 -  case 1:
 -    error(0, "%s:%d: missing port name/number",
 -        cs->path, cs->line);
 -    return -1;
 -  case 2:
 -    return 0;
 -  default:
 -    error(0, "%s:%d: expected ADDRESS PORT",
 -        cs->path, cs->line);
 -    return -1;
 -  }
 -}
 -
 -static int validate_port(const struct config_state attribute((unused)) *cs,
 -                       int nvec,
 -                       char attribute((unused)) **vec) {
 -  switch(nvec) {
 -  case 0:
 -    error(0, "%s:%d: missing address",
 -        cs->path, cs->line);
 -    return -1;
 -  case 1:
 -  case 2:
 -    return 0;
 -  default:
 -    error(0, "%s:%d: expected [ADDRESS] PORT",
 -        cs->path, cs->line);
 -    return -1;
 -  }
 -}
 -
  static int validate_algo(const struct config_state attribute((unused)) *cs,
                         int nvec,
                         char **vec) {
@@@ -870,31 -890,6 +871,31 @@@ static int validate_backend(const struc
    return 0;
  }
  
 +static int validate_pausemode(const struct config_state attribute((unused)) *cs,
 +                              int nvec,
 +                              char **vec) {
 +  if(nvec == 1 && (!strcmp(vec[0], "silence") || !strcmp(vec[0], "suspend")))
 +    return 0;
 +  error(0, "%s:%d: invalid pause mode", cs->path, cs->line);
 +  return -1;
 +}
 +
 +static int validate_destaddr(const struct config_state attribute((unused)) *cs,
 +                           int nvec,
 +                           char **vec) {
 +  struct netaddress na[1];
 +
 +  if(netaddress_parse(na, nvec, vec)) {
 +    error(0, "%s:%d: invalid network address", cs->path, cs->line);
 +    return -1;
 +  }
 +  if(!na->address) {
 +    error(0, "%s:%d: destination address required", cs->path, cs->line);
 +    return -1;
 +  }
 +  return 0;
 +}
 +
  /** @brief Item name and and offset */
  #define C(x) #x, offsetof(struct config, x)
  /** @brief Item name and and offset */
@@@ -906,13 -901,13 +907,13 @@@ static const struct conf conf[] = 
    { C(allow),            &type_stringlist_accum, validate_allow },
    { C(api),              &type_string,           validate_backend },
    { C(authorization_algorithm), &type_string,    validate_algo },
 -  { C(broadcast),        &type_stringlist,       validate_addrport },
 -  { C(broadcast_from),   &type_stringlist,       validate_addrport },
 +  { C(broadcast),        &type_netaddress,       validate_destaddr },
 +  { C(broadcast_from),   &type_netaddress,       validate_any },
    { C(channel),          &type_string,           validate_any },
    { C(checkpoint_kbyte), &type_integer,          validate_non_negative },
    { C(checkpoint_min),   &type_integer,          validate_non_negative },
    { C(collection),       &type_collections,      validate_any },
 -  { C(connect),          &type_stringlist,       validate_addrport },
 +  { C(connect),          &type_netaddress,       validate_destaddr },
    { C(cookie_login_lifetime),  &type_integer,    validate_positive },
    { C(cookie_key_lifetime),  &type_integer,      validate_positive },
    { C(dbversion),        &type_integer,          validate_positive },
    { C(gap),              &type_integer,          validate_non_negative },
    { C(history),          &type_integer,          validate_positive },
    { C(home),             &type_string,           validate_isabspath },
 -  { C(listen),           &type_stringlist,       validate_port },
 +  { C(listen),           &type_netaddress,       validate_any },
    { C(lock),             &type_boolean,          validate_any },
    { C(mail_sender),      &type_string,           validate_any },
    { C(mixer),            &type_string,           validate_any },
    { C(nice_speaker),     &type_integer,          validate_any },
    { C(noticed_history),  &type_integer,          validate_positive },
    { C(password),         &type_string,           validate_any },
 +  { C(pause_mode),       &type_string,           validate_pausemode },
    { C(player),           &type_stringlist_accum, validate_player },
    { C(plugins),          &type_string_accum,     validate_isdir },
    { C(prefsync),         &type_integer,          validate_positive },
    { C(reminder_interval), &type_integer,         validate_positive },
    { C(remote_userman),   &type_boolean,          validate_any },
    { C2(restrict, restrictions),         &type_restrict,         validate_any },
 +  { C(rtp_delay_threshold), &type_integer,       validate_positive },
    { C(sample_format),    &type_sample_format,    validate_sample_format },
    { C(scratch),          &type_string_accum,     validate_isreg },
    { C(sendmail),         &type_string,           validate_isabspath },
@@@ -1199,10 -1192,6 +1200,10 @@@ static struct config *config_default(vo
                       default_players[n], "disorder-tracklength", (char *)0))
        exit(1);
    }
 +  c->broadcast.af = -1;
 +  c->broadcast_from.af = -1;
 +  c->listen.af = -1;
 +  c->connect.af = -1;
    return c;
  }
  
@@@ -1274,7 -1263,7 +1275,7 @@@ static void config_postdefaults(struct 
    if(!c->api) {
      if(c->speaker_command)
        c->api = xstrdup("command");
 -    else if(c->broadcast.n)
 +    else if(c->broadcast.af != -1)
        c->api = xstrdup("rtp");
      else if(config_uaudio_apis)
        c->api = xstrdup(config_uaudio_apis[0]->name);
    if(server) {
      if(!strcmp(c->api, "command") && !c->speaker_command)
        fatal(0, "'api command' but speaker_command is not set");
 -    if((!strcmp(c->api, "rtp")) && !c->broadcast.n)
 +    if((!strcmp(c->api, "rtp")) && c->broadcast.af == -1)
        fatal(0, "'api rtp' but broadcast is not set");
    }
    /* Override sample format */