chiark / gitweb /
Merge memory hygeine branch
authorRichard Kettlewell <rjk@greenend.org.uk>
Sun, 18 Jul 2010 16:08:21 +0000 (17:08 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sun, 18 Jul 2010 16:08:21 +0000 (17:08 +0100)
1  2 
disobedience/login.c
lib/Makefile.am
lib/client.c
lib/configuration.c
lib/configuration.h
lib/queue.h

diff --combined disobedience/login.c
index a02c1c6e698188013c2a5e80051a5083ab8d92ed,90eaa0dde4ddcd30dbd7b4f9065b35a2720538c4..0c6e7d74dd44756d10f123f6bbaba055aafc59e3
@@@ -120,11 -120,13 +120,13 @@@ static void set_service(struct config *
  }
  
  static void set_username(struct config *c, const char *s) {
-   c->username = s;
+   xfree(c->username);
+   c->username = xstrdup(s);
  }
  
  static void set_password(struct config *c, const char *s) {
-   c->password = s;
+   xfree(c->password);
+   c->password = xstrdup(s);
  }
  
  /** @brief Table used to generate the form */
@@@ -230,12 -232,6 +232,12 @@@ static void login_cancel(GtkButton attr
    gtk_widget_destroy(login_window);
  }
  
 +/** @brief User pressed cancel in the login window */
 +static void login_help(GtkButton attribute((unused)) *button,
 +                       gpointer attribute((unused)) userdata) {
 +  popup_help("intro.html#login");
 +}
 +
  /** @brief Keypress handler */
  static gboolean login_keypress(GtkWidget attribute((unused)) *widget,
                                 GdkEventKey *event,
  /* Buttons that appear at the bottom of the window */
  static struct button buttons[] = {
    {
 -    "Login",
 -    login_ok,
 -    "(Re-)connect using these settings",
 -    0
 +    GTK_STOCK_HELP,
 +    login_help,
 +    "Go to manual",
 +    0,
 +    gtk_box_pack_start,
    },
    {
      GTK_STOCK_CLOSE,
      login_cancel,
      "Discard changes and close window",
 -    0
 +    0,
 +    gtk_box_pack_end,
 +  },
 +  {
 +    "Login",
 +    login_ok,
 +    "(Re-)connect using these settings",
 +    0,
 +    gtk_box_pack_end,
    },
  };
  
diff --combined lib/Makefile.am
index ff0eb8b18074c706f70162946386e19b641cde8d,ec674f6fcdd0cc3b752bd2e4ee5e2f12be1e2bfb..eea622032829866a1af95a9ed135fd8d5d140d74
@@@ -25,7 -25,7 +25,7 @@@ els
  TRACKDB=trackdb-stub.c
  endif
  
- libdisorder_a_SOURCES=charset.c charset.h             \
+ libdisorder_a_SOURCES=charset.c charsetf.c charset.h  \
        addr.c addr.h                                   \
        arcfour.c arcfour.h                             \
        authhash.c authhash.h                           \
@@@ -52,7 -52,6 +52,7 @@@
        heap.h                                          \
        hex.c hex.h                                     \
        hostname.c hostname.h                           \
 +      hreader.c hreader.h                             \
        ifreq.c ifreq.h                                 \
        inputline.c inputline.h                         \
        kvp.c kvp.h                                     \
@@@ -92,7 -91,6 +92,7 @@@
        unicode.h unicode.c                             \
        unidata.h unidata.c                             \
        vacopy.h                                        \
 +      validity.c validity.h                           \
        vector.c vector.h                               \
        version.c version.h                             \
        wav.h wav.c                                     \
@@@ -123,7 -121,6 +123,7 @@@ definitions.h: Makefil
        echo "#define PKGCONFDIR \"${sysconfdir}/\"PACKAGE" >> $@.new
        echo "#define PKGSTATEDIR \"${localstatedir}/\"PACKAGE" >> $@.new
        echo "#define PKGDATADIR \"${pkgdatadir}/\"" >> $@.new
 +      echo "#define DOCHTMLDIR \"${dochtmldir}\"" >> $@.new
        echo "#define SBINDIR \"${sbindir}/\"" >> $@.new
        echo "#define BINDIR \"${bindir}/\"" >> $@.new
        echo "#define FINKBINDIR \"${finkbindir}/\"" >> $@.new
@@@ -137,6 -134,10 +137,6 @@@ defs.lo: definitions.h versionstring.
  rebuild-unicode:
        cd ${srcdir} && ${top_srcdir}/scripts/make-unidata
  
 -%.i: %.c
 -      $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) -c $< > $@.new
 -      mv $@.new $@
 -
  CLEANFILES=definitions.h definitions.h.new version-string versionstring.h \
           *.gcda *.gcov *.gcno *.c.html index.html
  
diff --combined lib/client.c
index 00727ef010e78f62e3e6adbc0f771b2da9ba1f17,50f718466922f83707fd90568b5d3855fd43ec4a..2cbcfa76201324f07dc0668975b5dd5c51a98291
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * This file is part of DisOrder.
-  * Copyright (C) 2004-2008 Richard Kettlewell
+  * Copyright (C) 2004-2009 Richard Kettlewell
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
@@@ -141,10 -141,12 +141,12 @@@ static int check_response(disorder_clie
    else if(rc / 100 == 2) {
      if(rp)
        *rp = (rc % 10 == 9) ? 0 : xstrdup(r + 4);
+     xfree(r);
      return 0;
    } else {
      if(c->verbose)
        disorder_error(0, "from %s: %s", c->ident, utf82mb(r));
+     xfree(r);
      return rc;
    }
  }
@@@ -200,6 -202,7 +202,7 @@@ static int disorder_simple_v(disorder_c
      D(("command: %s", d.vec));
      if(fputs(d.vec, c->fpout) < 0)
        goto write_error;
+     xfree(d.vec);
      if(body) {
        if(nbody < 0)
          for(nbody = 0; body[nbody]; ++nbody)
@@@ -291,7 -294,9 +294,9 @@@ static int dequote(int rc, char **rp) 
  
    if(!rc) {
      if((rr = split(*rp, 0, SPLIT_QUOTES, 0, 0)) && *rr) {
+       xfree(*rp);
        *rp = *rr;
+       xfree(rr);
        return 0;
      }
      disorder_error(0, "invalid reply: %s", *rp);
@@@ -316,13 -321,13 +321,13 @@@ int disorder_connect_generic(struct con
                               const char *username,
                               const char *password,
                               const char *cookie) {
-   int fd = -1, fd2 = -1, nrvec, rc;
-   unsigned char *nonce;
+   int fd = -1, fd2 = -1, nrvec = 0, rc;
+   unsigned char *nonce = NULL;
    size_t nl;
-   const char *res;
-   char *r, **rvec;
+   char *res = NULL;
+   char *r = NULL, **rvec = NULL;
    const char *protocol, *algorithm, *challenge;
-   struct sockaddr *sa;
+   struct sockaddr *sa = NULL;
    socklen_t salen;
  
    if((salen = find_server(conf, &sa, &c->ident)) == (socklen_t)-1)
      disorder_error(0, "cannot parse server greeting %s", r);
      goto error;
    }
-   protocol = *rvec++;
+   protocol = rvec[0];
    if(strcmp(protocol, "2")) {
      c->last = "unknown protocol version";
      disorder_error(0, "unknown protocol version: %s", protocol);
      goto error;
    }
-   algorithm = *rvec++;
-   challenge = *rvec++;
+   algorithm = rvec[1];
+   challenge = rvec[2];
    if(!(nonce = unhex(challenge, &nl)))
      goto error;
    if(cookie) {
    if((rc = disorder_simple(c, 0, "user", username, res, (char *)0)))
      goto error_rc;
    c->user = xstrdup(username);
+   xfree(res);
+   free_strings(nrvec, rvec);
+   xfree(nonce);
+   xfree(sa);
+   xfree(r);
    return 0;
  error:
    rc = -1;
@@@ -505,9 -515,11 +515,11 @@@ int disorder_close(disorder_client *c) 
      }
      c->fpout = 0;
    }
+   xfree(c->ident);
    c->ident = 0;
+   xfree(c->user);
    c->user = 0;
 -  return 0;
 +  return ret;
  }
  
  /** @brief Play a track
@@@ -641,6 -653,7 +653,7 @@@ static int disorder_somequeue(disorder_
      if(!strcmp(l, ".")) {
        *qt = 0;
        *qp = qh;
+       xfree(l);
        return 0;
      }
      q = xmalloc(sizeof *q);
        *qt = q;
        qt = &q->next;
      }
+     xfree(l);
    }
    if(ferror(c->fpin)) {
      byte_xasprintf((char **)&c->last, "input error: %s", strerror(errno));
@@@ -700,9 -714,11 +714,11 @@@ static int readlist(disorder_client *c
        if(nvecp)
        *nvecp = v.nvec;
        *vecp = v.vec;
+       xfree(l);
        return 0;
      }
-     vector_append(&v, l + (*l == '.'));
+     vector_append(&v, xstrdup(l + (*l == '.')));
+     xfree(l);
    }
    if(ferror(c->fpin)) {
      byte_xasprintf((char **)&c->last, "input error: %s", strerror(errno));
@@@ -853,7 -869,9 +869,9 @@@ int disorder_prefs(disorder_client *c, 
      k->name = pvec[0];
      k->value = pvec[1];
      kp = &k->next;
+     xfree(pvec);
    }
+   free_strings(nvec, vec);
    *kp = 0;
    return 0;
  }
diff --combined lib/configuration.c
index 88cfbf280a6febfaca350b3492942760352247ad,c059bf7718400da36c086dbfeedd7af0a067dc34..53fddd5881318e4937a798e612abfc79da0771be
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * This file is part of DisOrder.
 - * Copyright (C) 2004-2009 Richard Kettlewell
 + * Copyright (C) 2004-2010 Richard Kettlewell
   * Portions copyright (C) 2007 Mark Wooding
   *
   * This program is free software: you can redistribute it and/or modify
@@@ -52,7 -52,7 +52,7 @@@
  
  /** @brief Path to config file 
   *
 - * set_configfile() sets the deafult if it is null.
 + * set_configfile() sets the default if it is null.
   */
  char *configfile;
  
@@@ -240,6 -240,7 +240,7 @@@ static int set_string(const struct conf
                   cs->path, cs->line, whoami->name);
      return -1;
    }
+   xfree(VALUE(cs->config, char *));
    VALUE(cs->config, char *) = xstrdup(vec[0]);
    return 0;
  }
@@@ -520,8 -521,7 +521,7 @@@ static int set_rights(const struct conf
                   cs->path, cs->line, vec[0]);
      return -1;
    }
-   *ADDRESS(cs->config, char *) = vec[0];
-   return 0;
+   return set_string(cs, whoami, nvec, vec);
  }
  
  static int set_netaddress(const struct config_state *cs,
@@@ -644,7 -644,7 +644,7 @@@ static const struct conftyp
    type_namepart = { set_namepart, free_namepartlist },
    type_transform = { set_transform, free_transformlist },
    type_netaddress = { set_netaddress, free_netaddress },
-   type_rights = { set_rights, free_none };
+   type_rights = { set_rights, free_string };
  
  /* specific validation routine */
  
@@@ -835,7 -835,9 +835,7 @@@ static int validate_positive(const stru
  static int validate_isauser(const struct config_state *cs,
                            int attribute((unused)) nvec,
                            char **vec) {
 -  struct passwd *pw;
 -
 -  if(!(pw = getpwnam(vec[0]))) {
 +  if(!getpwnam(vec[0])) {
      disorder_error(0, "%s:%d: no such user as '%s'", cs->path, cs->line, vec[0]);
      return -1;
    }
@@@ -1045,6 -1047,7 +1045,7 @@@ static int validate_destaddr(const stru
      disorder_error(0, "%s:%d: destination address required", cs->path, cs->line);
      return -1;
    }
+   xfree(na->address);
    return 0;
  }
  
@@@ -1066,8 -1069,8 +1067,8 @@@ static const struct conf conf[] = 
    { C(checkpoint_min),   &type_integer,          validate_non_negative },
    { C(collection),       &type_collections,      validate_any },
    { C(connect),          &type_netaddress,       validate_destaddr },
 -  { C(cookie_login_lifetime),  &type_integer,    validate_positive },
    { C(cookie_key_lifetime),  &type_integer,      validate_positive },
 +  { C(cookie_login_lifetime),  &type_integer,    validate_positive },
    { C(dbversion),        &type_integer,          validate_positive },
    { C(default_rights),   &type_rights,           validate_any },
    { C(device),           &type_string,           validate_any },
    { C(lock),             &type_boolean,          validate_any },
    { C(mail_sender),      &type_string,           validate_any },
    { C(mixer),            &type_string,           validate_any },
 +  { C(mount_rescan),     &type_boolean,          validate_any },
    { C(multicast_loop),   &type_boolean,          validate_any },
    { C(multicast_ttl),    &type_integer,          validate_non_negative },
    { C(namepart),         &type_namepart,         validate_any },
    { C(plugins),          &type_string_accum,     validate_isdir },
    { C(prefsync),         &type_integer,          validate_positive },
    { C(queue_pad),        &type_integer,          validate_positive },
 -  { C(replay_min),       &type_integer,          validate_non_negative },
    { C(refresh),          &type_integer,          validate_positive },
 +  { C(refresh_min),      &type_integer,          validate_non_negative },
    { C(reminder_interval), &type_integer,         validate_positive },
    { C(remote_userman),   &type_boolean,          validate_any },
 +  { C(replay_min),       &type_integer,          validate_non_negative },
    { C2(restrict, restrictions),         &type_restrict,         validate_any },
    { C(rtp_delay_threshold), &type_integer,       validate_positive },
    { C(sample_format),    &type_sample_format,    validate_sample_format },
@@@ -1174,7 -1175,9 +1175,9 @@@ static int config_set_args(const struc
      vector_append(v, s);
    va_end(ap);
    vector_terminate(v);
-   return config_set(cs, v->nvec, v->vec);
+   int rc = config_set(cs, v->nvec, v->vec);
+   xfree(v->vec);
+   return rc;
  }
  
  /** @brief Error callback used by config_include()
@@@ -1337,7 -1340,6 +1340,7 @@@ static struct config *config_default(vo
    logname = pw->pw_name;
    c->username = xstrdup(logname);
    c->refresh = 15;
 +  c->refresh_min = 1;
    c->prefsync = 0;
    c->signal = SIGKILL;
    c->alias = xstrdup("{/artist}{/album}{/title}{ext}");
    c->sox_generation = DEFAULT_SOX_GENERATION;
    c->playlist_max = INT_MAX;            /* effectively no limit */
    c->playlist_lock_timeout = 10;        /* 10s */
 +  c->mount_rescan = 1;
    /* Default stopwords */
    if(config_set(&cs, (int)NDEFAULT_STOPWORDS, (char **)default_stopwords))
      exit(1);
@@@ -1417,7 -1418,7 +1420,7 @@@ static void set_configfile(void) 
   *
   * @p c is indeterminate after this function is called.
   */
static void config_free(struct config *c) {
+ void config_free(struct config *c) {
    int n;
  
    if(c) {
@@@ -1731,19 -1732,6 +1734,19 @@@ static int namepartlist_compare(const s
      return 0;
  }
  
 +/** @brief Verify configuration table.
 + * @return The number of problems found
 +*/
 +int config_verify(void) {
 +  int fails = 0;
 +  for(size_t n = 1; n < sizeof conf / sizeof *conf; ++n)
 +    if(strcmp(conf[n-1].name, conf[n].name) >= 0) {
 +      fprintf(stderr, "%s >= %s\n", conf[n-1].name, conf[n].name);
 +      ++fails;
 +    }
 +  return fails;
 +}
 +
  /*
  Local Variables:
  c-basic-offset:2
diff --combined lib/configuration.h
index 22e107d62be9b746b379b9b551317bed28095a3a,f1794aa1c5b92dd03d316932ea544dc5c7982cc5..8255db2e6e7268c4c411bf71ab40847abd199118
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * This file is part of DisOrder.
 - * Copyright (C) 2004-2009 Richard Kettlewell
 + * Copyright (C) 2004-2010 Richard Kettlewell
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
@@@ -195,10 -195,10 +195,10 @@@ struct config 
    const char *home;
  
    /** @brief Login username */
-   const char *username;
+   char *username;
  
    /** @brief Login password */
-   const char *password;
+   char *password;
  
    /** @brief Address to connect to */
    struct netaddress connect;
    /** @brief Maximum refresh interval for web interface (seconds) */
    long refresh;
  
 +  /** @brief Minimum refresh interval for web interface (seconds) */
 +  long refresh_min;
 +
    /** @brief Facilities restricted to trusted users
     *
     * A bitmap of @ref RESTRICT_SCRATCH, @ref RESTRICT_REMOVE and @ref
  
    /** @brief Maximum bias */
    long new_bias;
 -  
 +
 +  /** @brief Rescan on (un)mount */
 +  int mount_rescan;
 +
    /* derived values: */
    int nparts;                         /* number of distinct name parts */
    char **parts;                               /* name part list  */
@@@ -326,8 -320,8 +326,10 @@@ char *config_usersysconf(const struct p
  char *config_private(void);
  /* get the private config file */
  
 +int config_verify(void);
 +
+ void config_free(struct config *c);
  extern char *configfile;
  extern int config_per_user;
  
diff --combined lib/queue.h
index c287ebe950afd4eb9ce55e989be998c6c1713796,c7dbfd230268b653e4055b60304d893f5a77704b..2219763f6539cd5da3b83b9a01979ced7ea43872
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * This file is part of DisOrder.
-  * Copyright (C) 2004-2008 Richard Kettlewell
+  * Copyright (C) 2004-2009 Richard Kettlewell
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
@@@ -188,13 -188,6 +188,13 @@@ struct queue_entry 
    /** @brief How much of track has been played so far (seconds) */
    long sofar;
  
 +  /** @brief True if track preparation is underway
 +   *
 +   * This is set when a decoder has been started and is expected to connect to
 +   * the speaker, but the speaker has not sent as @ref SM_ARRIVED message back
 +   * yet. */
 +  int preparing;
 +
    /** @brief True if decoder is connected to speaker 
     *
     * This is not a @ref playing_state for a couple of reasons
@@@ -238,6 -231,8 +238,8 @@@ int queue_unmarshall_vec(struct queue_e
  char *queue_marshall(const struct queue_entry *q);
  /* marshall @q@ into a UTF-8 string */
  
+ void queue_free(struct queue_entry *q, int rest);
  #endif /* QUEUE_H */
  
  /*