Use of libgc means we don't have to worry about memory leakage as such
in most of the code. But in some cases libgc isn't appropriate and
GTK+ doesn't get on well with it (or at least used not to).
}
if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration");
if(user) {
}
if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration");
if(user) {
- config->username = user;
+ xfree(config->username);
+ config->username = xstrdup(user);
- if(password)
- config->password = password;
+ if(password) {
+ xfree(config->password);
+ config->password = xstrdup(password);
+ }
if(local)
config->connect.af = -1;
if(wfr)
if(local)
config->connect.af = -1;
if(wfr)
vector_append(&args, nullcheck(mb2utf8(argv[n + j])));
vector_terminate(&args);
commands[i].fn(args.vec + 1);
vector_append(&args, nullcheck(mb2utf8(argv[n + j])));
vector_terminate(&args);
commands[i].fn(args.vec + 1);
n += j;
}
if(client && disorder_close(client)) exit(EXIT_FAILURE);
if(fclose(stdout) < 0) disorder_fatal(errno, "error closing stdout");
n += j;
}
if(client && disorder_close(client)) exit(EXIT_FAILURE);
if(fclose(stdout) < 0) disorder_fatal(errno, "error closing stdout");
}
static void set_username(struct config *c, const char *s) {
}
static void set_username(struct config *c, const char *s) {
+ xfree(c->username);
+ c->username = xstrdup(s);
}
static void set_password(struct config *c, const char *s) {
}
static void set_password(struct config *c, const char *s) {
+ xfree(c->password);
+ c->password = xstrdup(s);
}
/** @brief Table used to generate the form */
}
/** @brief Table used to generate the form */
int byte_vasprintf(char **ptrp,
const char *fmt,
va_list ap) {
int byte_vasprintf(char **ptrp,
const char *fmt,
va_list ap) {
struct dynstr d;
int n;
dynstr_init(&d);
struct dynstr d;
int n;
dynstr_init(&d);
- if((n = byte_vsinkprintf(sink_dynstr(&d), fmt, ap)) >= 0) {
+ s = sink_dynstr(&d);
+ n = byte_vsinkprintf(s, fmt, ap);
+ xfree(s);
+ if(n >= 0) {
dynstr_terminate(&d);
*ptrp = d.vec;
}
dynstr_terminate(&d);
*ptrp = d.vec;
}
cs->path, cs->line, whoami->name);
return -1;
}
cs->path, cs->line, whoami->name);
return -1;
}
+ xfree(VALUE(cs->config, char *));
VALUE(cs->config, char *) = xstrdup(vec[0]);
return 0;
}
VALUE(cs->config, char *) = xstrdup(vec[0]);
return 0;
}
cs->path, cs->line, vec[0]);
return -1;
}
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,
}
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_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 */
/* specific validation routine */
disorder_error(0, "%s:%d: destination address required", cs->path, cs->line);
return -1;
}
disorder_error(0, "%s:%d: destination address required", cs->path, cs->line);
return -1;
}
vector_append(v, s);
va_end(ap);
vector_terminate(v);
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()
}
/** @brief Error callback used by config_include()
*
* @p c is indeterminate after this function is called.
*/
*
* @p c is indeterminate after this function is called.
*/
-static void config_free(struct config *c) {
+void config_free(struct config *c) {
const char *home;
/** @brief Login username */
const char *home;
/** @brief Login username */
/** @brief Login password */
/** @brief Login password */
/** @brief Address to connect to */
struct netaddress connect;
/** @brief Address to connect to */
struct netaddress connect;
char *config_private(void);
/* get the private config file */
char *config_private(void);
/* get the private config file */
+void config_free(struct config *c);
+
extern char *configfile;
extern int config_per_user;
extern char *configfile;
extern int config_per_user;
+/** @brief Free a string list */
+void free_strings(int nvec, char **vec) {
+ for(int n = 0; n < nvec; ++n)
+ xfree(vec[n]);
+ xfree(vec);
+}
+
+/** @brief Free and re-initialize a vector */
+void vector_clear(struct vector *v) {
+ free_strings(v->nvec, v->vec);
+ vector_init(v);
+}
+
/*
Local Variables:
c-basic-offset:2
/*
Local Variables:
c-basic-offset:2
dynstr_append_bytes(v, ptr, strlen(ptr));
}
dynstr_append_bytes(v, ptr, strlen(ptr));
}
+void free_strings(int nvec, char **vec);
+void vector_clear(struct vector *v);
+