break;
case 'c': /* config file */
+ free(confbase);
confbase = xstrdup(optarg);
break;
case 'L': /* no detach */
#ifndef HAVE_MLOCKALL
logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]);
- return false;
+ goto exit_fail;
#else
do_mlock = true;
break;
break;
case 'n': /* net name given */
+ free(netname);
netname = xstrdup(optarg);
break;
cfg = parse_config_line(optarg, NULL, ++lineno);
if(!cfg) {
- return false;
+ goto exit_fail;
}
list_insert_tail(cmdline_conf, cfg);
case 'R':
case 'U':
logger(DEBUG_ALWAYS, LOG_ERR, "The %s option is not supported on this platform.", argv[optind - 1]);
- return false;
+ goto exit_fail;
#else
case 'R': /* chroot to NETNAME dir */
}
if(optarg) {
+ free(logfilename);
logfilename = xstrdup(optarg);
}
break;
case 5: /* open control socket here */
+ free(pidfilename);
pidfilename = xstrdup(optarg);
break;
case '?': /* wrong options */
usage(true);
- return false;
+ goto exit_fail;
default:
break;
if(optind < argc) {
fprintf(stderr, "%s: unrecognized argument '%s'\n", argv[0], argv[optind]);
usage(true);
- return false;
+ goto exit_fail;
}
if(!netname && (netname = getenv("NETNAME"))) {
if(netname && !check_netname(netname, false)) {
fprintf(stderr, "Invalid character in netname!\n");
- return false;
+ goto exit_fail;
}
if(netname && !check_netname(netname, true)) {
}
return true;
+
+exit_fail:
+ free_names();
+ free(cmdline_conf);
+ cmdline_conf = NULL;
+ return false;
}
static bool drop_privs(void) {
# define setpriority(level) (setpriority(PRIO_PROCESS, 0, (level)))
#endif
+static void cleanup() {
+ if(config_tree) {
+ exit_configuration(&config_tree);
+ }
+
+ free(cmdline_conf);
+ free_names();
+}
+
int main(int argc, char **argv) {
program_name = argv[0];
}
make_names(true);
+ atexit(cleanup);
+
chdir(confbase);
#ifdef HAVE_MINGW
crypto_exit();
- exit_configuration(&config_tree);
- free(cmdline_conf);
- free_names();
-
return status;
}