summaryrefslogtreecommitdiff
path: root/src/module/module.c
blob: 22f6142f8039a65d1dd8f6a5416a6fa7aa747e6e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "module.h"

char const *Arg0;

void __attribute__((noreturn)) usage(void)
{
	WARNINGS_IGNORE("-Wformat-nonliteral")
	fprintf(stderr, Usage, Arg0);
	WARNINGS_RESTORE
	exit(EX_USAGE);
}

static ucl_object_t *
Parse(char const *Arg)
{
	struct ucl_parser *Parser = ucl_parser_new(0);
	if(ucl_parser_add_string(Parser, Arg, 0) == false)
	{
		fprintf(stderr, "Unable to parse state file: %s\n", ucl_parser_get_error(Parser));
		ucl_parser_free(Parser);
		exit(EX_CONFIG);
	}
	ucl_object_t *root = ucl_parser_get_object(Parser);
	ucl_parser_free(Parser);
	return root;
}

int
main(int ArgCount, char **Arg)
{
	Arg0 = Arg[0];
	int C;
	while((C = getopt(ArgCount, Arg, "")) != -1)
	{
		switch(C)
		{
			case '?':
			default: usage();
		}
	}
	ArgCount -= optind;
	Arg += optind;
	if(ArgCount == 0) usage();
	char const *Command = Arg[0];
	--ArgCount;
	++Arg;
	int Result;
	if(strcmp(Command, "start") == 0)
	{
		if(ArgCount != 2) usage();
		char const *Name = Arg[0];
		if(isprints(Name) == false)
		{
			fprintf(stderr, "Name is non-printable\n");
			return -1;
		}
		ucl_object_t *Configuration = Parse(Arg[1]);
		Result                      = start(Name, Configuration);
		ucl_object_unref(Configuration);
	} else if(strcmp(Command, "stop") == 0)
	{
		if(ArgCount != 3) usage();
		char const *Name = Arg[0];
		if(isprints(Name) == false)
		{
			fprintf(stderr, "Name is non-printable\n");
			return -1;
		}
		ucl_object_t *Configuration = Parse(Arg[1]);
		ucl_object_t *Data          = Parse(Arg[2]);
		Result                      = stop(Name, Configuration, Data);
		ucl_object_unref(Configuration);
		ucl_object_unref(Data);
	} else if(strcmp(Command, "get-endpoint") == 0)
	{
		if(ArgCount != 4) usage();
		char const *Name = Arg[0];
		if(isprints(Name) == false)
		{
			fprintf(stderr, "Name is non-printable\n");
			return -1;
		}
		ucl_object_t *Configuration = Parse(Arg[1]);
		ucl_object_t *Data          = Parse(Arg[2]);
		char const   *Interface     = Arg[3];
		Result                      = get_endpoint(Name, Configuration, Data, Interface);
		ucl_object_unref(Configuration);
		ucl_object_unref(Data);
	} else if(strcmp(Command, "cmd") == 0)
	{
		if(ArgCount < 3) usage();
		char const *Name = Arg[0];
		if(isprints(Name) == false)
		{
			fprintf(stderr, "Name is non-printable\n");
			return -1;
		}
		ucl_object_t *Configuration = Parse(Arg[1]);
		ucl_object_t *Data          = Parse(Arg[2]);
		Arg += 3;
		ArgCount -= 3;
		Result = cmd(Name, Configuration, Data, (size_t)ArgCount, Arg);
		ucl_object_unref(Configuration);
		ucl_object_unref(Data);
	} else if(strcmp(Command, "mod") == 0)
	{
		if(ArgCount < 3) usage();
		char const *Name = Arg[0];
		if(isprints(Name) == false)
		{
			fprintf(stderr, "Name is non-printable\n");
			return -1;
		}
		ucl_object_t *Configuration = Parse(Arg[1]);
		ucl_object_t *Data          = Parse(Arg[2]);
		Arg += 3;
		ArgCount -= 3;
		Result = mod(Name, Configuration, Data, (size_t)ArgCount, Arg);
		ucl_object_unref(Configuration);
		ucl_object_unref(Data);
	} else
	{
		usage();
	}
	return Result;
}