/*
* 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
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;
}
}
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)
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);
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;
}
c->fpout = 0;
}
+ xfree(c->ident);
c->ident = 0;
+ xfree(c->user);
c->user = 0;
- return 0;
+ return ret;
}
/** @brief Play a track
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));
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));
k->name = pvec[0];
k->value = pvec[1];
kp = &k->next;
+ xfree(pvec);
}
+ free_strings(nvec, vec);
*kp = 0;
return 0;
}
/*
* 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
/** @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;
cs->path, cs->line, whoami->name);
return -1;
}
+ xfree(VALUE(cs->config, char *));
VALUE(cs->config, char *) = xstrdup(vec[0]);
return 0;
}
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,
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 */
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;
}
disorder_error(0, "%s:%d: destination address required", cs->path, cs->line);
return -1;
}
+ xfree(na->address);
return 0;
}
{ 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 },
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()
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);
*
* @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) {
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