-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Attempt to straighten up joold's argv
For #410. Ugh. Ran out of time, and I still have some issues with it. Also, it's missing documentation. Will keep grinding next weekend.
- Loading branch information
Showing
10 changed files
with
546 additions
and
379 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,78 +1,210 @@ | ||
#include <errno.h> | ||
#include <pthread.h> | ||
#include <getopt.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <syslog.h> | ||
|
||
#include "log.h" | ||
#include "common/types.h" | ||
#include "common/xlat.h" | ||
#include "usr/joold/modsocket.h" | ||
#include "usr/joold/netsocket.h" | ||
#include "usr/joold/statsocket.h" | ||
|
||
static void cancel_thread(pthread_t thread) | ||
static const struct option OPTIONS[] = { | ||
{ | ||
.name = "version", | ||
.has_arg = no_argument, | ||
.val = 'V', | ||
}, { | ||
.name = "help", | ||
.has_arg = no_argument, | ||
.val = 'h', | ||
}, | ||
|
||
/* Files */ | ||
|
||
{ | ||
.name = "modsocket", | ||
.has_arg = required_argument, | ||
.val = 'm', | ||
}, { | ||
.name = "netsocket", | ||
.has_arg = required_argument, | ||
.val = 'n', | ||
}, { | ||
.name = "statsocket", | ||
.has_arg = required_argument, | ||
.val = 's', | ||
}, | ||
|
||
/* Modsocket */ | ||
|
||
{ | ||
.name = "instance", | ||
.has_arg = required_argument, | ||
.val = 'i', | ||
}, | ||
|
||
/* Netsocket */ | ||
|
||
{ | ||
.name = "--net.multicast.addr", | ||
.has_arg = required_argument, | ||
.val = 1100, | ||
}, { | ||
.name = "--net.multicast.port", | ||
.has_arg = required_argument, | ||
.val = 1101, | ||
}, { | ||
.name = "--net.interface.in", | ||
.has_arg = required_argument, | ||
.val = 1102, | ||
}, { | ||
.name = "--net.interface.out", | ||
.has_arg = required_argument, | ||
.val = 1103, | ||
}, { | ||
.name = "--net.ttl", | ||
.has_arg = required_argument, | ||
.val = 1104, | ||
}, | ||
|
||
/* Statsocket */ | ||
|
||
{ | ||
.name = "stats.address", | ||
.has_arg = required_argument, | ||
.val = 1200, | ||
}, { | ||
.name = "stats.port", | ||
.has_arg = required_argument, | ||
.val = 1201, | ||
}, | ||
{ 0 }, | ||
}; | ||
|
||
static void print_help(void) | ||
{ | ||
int error; | ||
printf("-V, --version Print program version number\n"); | ||
printf("-h, --help Print this\n\n"); | ||
|
||
printf("-m, --modsocket=FILE Path to file containing kernel socket config\n"); | ||
printf("-n, --netsocket=FILE Path to file containing network socket config\n"); | ||
printf("-s, --statsocket=FILE Path to file containing stats socket config\n\n"); | ||
|
||
error = pthread_cancel(thread); | ||
if (!error) | ||
pthread_join(thread, NULL); | ||
/* | ||
* else: | ||
* Well, `man 3 pthread_cancel` just `exit(EXIT_FAILURE)`s when | ||
* `pthread_cancel()` fails. | ||
* Let's instead be good citizens by closing the sockets anyway. | ||
*/ | ||
printf("-i, --instance=STRING Kernelspace Jool instance name\n"); | ||
printf(" (Default: \"default\")\n\n"); | ||
|
||
printf("--net.multicast.addr=ADDR Address where the sessions will be advertised\n"); | ||
printf("--net.multicast.port=STR UDP port where the sessions will be advertised\n"); | ||
printf("--net.interface.in=STR IPv4: IP_ADD_MEMBERSHIP; IPv6: IPV6_ADD_MEMBERSHIP\n"); | ||
printf(" (see ip(7))\n"); | ||
printf("--net.interface.out=STR IPv4: IP_MULTICAST_IF, IPv6: IPV6_MULTICAST_IF\n"); | ||
printf(" (see ip(7))\n"); | ||
printf("--net.ttl=INT Multicast datagram Time To Live\n\n"); | ||
|
||
printf("--stats.address=ADDR Address to bind the stats socket to\n"); | ||
printf("--stats.port=INT Port to bind the stats socket to\n"); | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
pthread_t mod2net_thread; | ||
pthread_t net2mod_thread; | ||
char const *OPTS = "Vhm:n:s:i:"; | ||
int opt; | ||
unsigned long ul; | ||
int error; | ||
|
||
printf("Remember that joold is intended as a daemon, so it outputs straight to syslog.\n"); | ||
printf("(Syslog normally sends messages to /var/log/syslog by default.)\n"); | ||
modcfg.iname = "default"; | ||
netcfg.ttl = 1; | ||
|
||
while ((opt = getopt_long(argc, argv, OPTS, OPTIONS, NULL)) != -1) { | ||
switch (opt) { | ||
case 'V': | ||
printf(JOOL_VERSION_STR "\n"); | ||
return 0; | ||
case 'h': | ||
print_help(); | ||
return 0; | ||
|
||
case 'm': | ||
error = modsocket_config(optarg); | ||
if (error) | ||
return error; | ||
break; | ||
case 'n': | ||
error = netsocket_config(optarg); | ||
if (error) | ||
return error; | ||
break; | ||
case 's': | ||
error = statsocket_config(optarg); | ||
if (error) | ||
return error; | ||
break; | ||
|
||
case 'i': | ||
modcfg.iname = optarg; | ||
break; | ||
|
||
case 1100: | ||
netcfg.enabled = true; | ||
netcfg.mcast_addr = optarg; | ||
break; | ||
case 1101: | ||
netcfg.enabled = true; | ||
netcfg.mcast_port = optarg; | ||
break; | ||
|
||
case 1102: | ||
netcfg.enabled = true; | ||
netcfg.in_interface = optarg; | ||
break; | ||
case 1103: | ||
netcfg.enabled = true; | ||
netcfg.out_interface = optarg; | ||
break; | ||
case 1104: | ||
netcfg.enabled = true; | ||
errno = 0; | ||
ul = strtoul(optarg, NULL, 10); | ||
if (ul > 255 || errno) { | ||
syslog(LOG_ERR, "ttl out of range: %s\n", optarg); | ||
return 1; | ||
} | ||
netcfg.ttl = ul; | ||
break; | ||
|
||
case 1200: | ||
statcfg.enabled = true; | ||
statcfg.address = optarg; | ||
break; | ||
case 1201: | ||
statcfg.enabled = true; | ||
statcfg.port = optarg; | ||
break; | ||
} | ||
} | ||
|
||
printf("joold is intended as a daemon, so it outputs straight to syslog.\n"); | ||
printf("The standard streams will mostly shut up from now on.\n"); | ||
printf("---------------------------------------------\n"); | ||
|
||
openlog("joold", 0, LOG_DAEMON); | ||
|
||
error = netsocket_setup(argc, argv); | ||
error = modsocket_setup(); | ||
if (error) | ||
goto end; | ||
error = modsocket_setup(argc, argv); | ||
if (error) { | ||
netsocket_teardown(); | ||
error = netsocket_start(); | ||
if (error) | ||
goto end; | ||
} | ||
error = statsocket_start(argc, argv); | ||
error = statsocket_start(); | ||
if (error) | ||
goto clean; | ||
|
||
error = pthread_create(&mod2net_thread, NULL, modsocket_listen, NULL); | ||
if (error) { | ||
pr_perror("Module-to-network thread initialization", error); | ||
goto clean; | ||
} | ||
error = pthread_create(&net2mod_thread, NULL, netsocket_listen, NULL); | ||
if (error) { | ||
pr_perror("Network-to-module thread initialization", error); | ||
cancel_thread(mod2net_thread); | ||
goto clean; | ||
} | ||
|
||
pthread_join(net2mod_thread, NULL); | ||
pthread_join(mod2net_thread, NULL); | ||
/* Fall through. */ | ||
goto end; | ||
|
||
clean: | ||
modsocket_teardown(); | ||
netsocket_teardown(); | ||
/* Fall through. */ | ||
modsocket_listen(NULL); /* Loops forever */ | ||
|
||
end: | ||
closelog(); | ||
if (error) | ||
fprintf(stderr, "joold error: %d\n", error); | ||
end: closelog(); | ||
fprintf(stderr, "joold error: %d\n", error); | ||
return error; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#include "usr/joold/json.h" | ||
|
||
#include <errno.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <sys/syslog.h> | ||
|
||
#include "usr/joold/log.h" | ||
#include "usr/util/file.h" | ||
|
||
int read_json(char const *filename, cJSON **out) | ||
{ | ||
char *file; | ||
cJSON *json; | ||
struct jool_result result; | ||
|
||
syslog(LOG_INFO, "Opening file %s...", filename); | ||
result = file_to_string(filename, &file); | ||
if (result.error) | ||
return pr_result(&result); | ||
|
||
json = cJSON_Parse(file); | ||
if (!json) { | ||
syslog(LOG_ERR, "JSON syntax error."); | ||
syslog(LOG_ERR, "The JSON parser got confused around about here:"); | ||
syslog(LOG_ERR, "%s", cJSON_GetErrorPtr()); | ||
free(file); | ||
return 1; | ||
} | ||
|
||
free(file); | ||
*out = json; | ||
return 0; | ||
} | ||
|
||
int json2str(cJSON *json, char const *key, char **dst) | ||
{ | ||
char *tmp; | ||
|
||
json = cJSON_GetObjectItem(json, key); | ||
if (!json) | ||
return 0; | ||
|
||
tmp = strdup(json->valuestring); | ||
if (tmp) | ||
return ENOMEM; | ||
|
||
*dst = tmp; | ||
return 0; | ||
} | ||
|
||
int json2int(cJSON *json, char const *key, int *dst) | ||
{ | ||
json = cJSON_GetObjectItem(json, key); | ||
if (!json) | ||
return 0; | ||
|
||
if (!(json->numflags & VALUENUM_INT)) { | ||
syslog(LOG_ERR, "%s '%s' is not a valid integer.", key, | ||
json->valuestring); | ||
return EINVAL; | ||
} | ||
|
||
*dst = json->valueint; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#ifndef SRC_USR_JOOLD_JSON_H_ | ||
#define SRC_USR_JOOLD_JSON_H_ | ||
|
||
#include "usr/util/cJSON.h" | ||
|
||
int read_json(char const *, cJSON **); | ||
|
||
int json2str(cJSON *, char const *, char **); | ||
int json2int(cJSON *, char const *, int *); | ||
|
||
#endif /* SRC_USR_JOOLD_JSON_H_ */ |
Oops, something went wrong.