Mercurial > irccd
annotate examples/sample-plugin.c @ 1085:91e3def8c708
irccdctl: fix server-part without reason
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 21 Jul 2021 07:48:41 +0200 |
parents | 8f26ee9cc6dd |
children | c3191ab50cee |
rev | line source |
---|---|
1009 | 1 /* |
2 * This is a sample plugin in native C API. | |
3 * | |
4 * Note: we recommend that C plugins should be used as last resort because any | |
5 * error will crash the whole daemon. It is also less convenient to share and | |
6 * update. | |
7 * | |
8 * You can use CMake to build and install it to appropriate place using the | |
9 * following code: | |
10 * | |
11 * find_package(irccd REQUIRED) | |
12 * irccd_define_c_plugin( | |
13 * MAME myplugin | |
14 * SOURCES muplugin.c | |
15 * ) | |
16 * | |
17 * You can also compile by hand using the pkg-config irccd file. | |
18 * | |
19 * cc myplugin.c -o myplugin.so $(pkg-config --libs --cflags irccd) | |
20 * | |
21 * All symbols exported from the file must start with the plugin file basename | |
22 * without its extension and with every non allowed character translated to | |
23 * `_'. For example if the plugin is name `example-stuff' symbol must start | |
24 * with `example_stuff_'. In this example we consider `example_`. | |
25 */ | |
26 | |
27 /* | |
28 * Include convention is using irccd/ prefix. | |
29 * | |
30 * The compat.h header contains additional BSD/POSIX extensions that may be | |
31 * missing on your system. It is optional unless you explicitly use them. | |
32 */ | |
33 | |
34 #include <string.h> | |
35 | |
36 #include <irccd/compat.h> | |
37 #include <irccd/event.h> | |
38 #include <irccd/server.h> | |
39 | |
40 /* | |
41 * This is the plugin identifier, every variable are optional. | |
42 */ | |
43 const char *example_description = "Example of C plugin" | |
44 const char *example_version = "0.1.0"; | |
45 const char *example_license = "ISC"; | |
46 const char *example_author = "Name and optional email"; | |
47 | |
48 /* | |
49 * get_options | get_templates | get_paths | |
50 * ---------------------------------------------------------------------- | |
51 * | |
52 * The following optional functions indicate to the daemon which keys are | |
53 * supported as options, templates and paths respectively. | |
54 * | |
55 * Note: even if get_paths is not present or return NULL, irccd allows `cache', | |
56 * `data' and `config' as standard keys. | |
57 * | |
58 * All three functions should return an array of strings which should be | |
59 * terminated with a NULL value. They should not be dynamically allocated | |
60 * because irccd does not assume they are. | |
61 */ | |
62 | |
63 const char ** | |
64 example_get_options(void) | |
65 { | |
66 /* Indicate to irccd we support options `level' and `language' */ | |
67 static const char *keys[] = { | |
68 "level", | |
69 "language", | |
70 NULL | |
71 }; | |
72 | |
73 return keys; | |
74 } | |
75 | |
76 const char ** | |
77 example_get_templates(void) | |
78 { | |
79 /* Indicate to irccd we support templates `start' and `finish' */ | |
80 static const char *keys[] = { | |
81 "start", | |
82 "finish", | |
83 NULL | |
84 }; | |
85 | |
86 return keys; | |
87 } | |
88 | |
89 /* | |
90 * get_option | get_template | get_path | |
91 * ---------------------------------------------------------------------- | |
92 * | |
93 * Those optional functions are analogous to their respective plural form | |
94 * except they take a key as parameter. | |
95 * | |
96 * The plugin can receive an unknown key from the user, NULL can be returned if | |
97 * they are not supported. | |
98 * | |
99 * The returned string isn't free'd by irccd so don't allocate any value | |
100 * without storing it somewhere if really needed. | |
101 */ | |
102 | |
103 const char * | |
104 example_get_option(const char *key) | |
105 { | |
106 if (strcmp(key, "level") == 0) | |
107 return "hard"; | |
108 else if (strcmp(key, "language") == 0) | |
109 return "french"; | |
110 | |
111 return NULL; | |
112 } | |
113 | |
114 const char * | |
115 example_get_template(const char *key) | |
116 { | |
117 if (strcmp(key, "start") == 0) | |
118 return "#{nickname}, the game has started"; | |
119 else if (strcmp(key, "finish") == 0) | |
120 return "#{nickname}, the game has finished"; | |
121 | |
122 return NULL; | |
123 } | |
124 | |
125 /* | |
126 * set_option | set_template | set_path | |
127 * ---------------------------------------------------------------------- | |
128 * | |
129 * Finally the three functions are used to set a new value as options, | |
130 * templates and paths respectively. Like their `get_*' counterpart, the plugin | |
131 * may receive a unknown key from the user in that case it should be simply | |
132 * ignored. | |
133 * | |
134 * Tip: the easiest to manage those is to use global fixed size strings. | |
135 */ | |
136 | |
137 void | |
138 example_set_option(const char *key, const char *value) | |
139 { | |
140 /* Assuming my_option_* variable exist. */ | |
141 if (strcmp(key, "level") == 0) | |
1079
8f26ee9cc6dd
misc: unconditionnally add BSD->POSIX extensions
David Demelier <markand@malikania.fr>
parents:
1009
diff
changeset
|
142 irc_util_strlcpy(my_option_level, value, sizeof (my_option_level)); |
1009 | 143 else if (strcmp(key, "language") == 0) |
1079
8f26ee9cc6dd
misc: unconditionnally add BSD->POSIX extensions
David Demelier <markand@malikania.fr>
parents:
1009
diff
changeset
|
144 irc_util_strlcpy(my_option_language, value, sizeof (my_option_language)); |
1009 | 145 } |
146 | |
147 void | |
148 example_set_template(const char *key) | |
149 { | |
150 /* Assuming my_template_* variable exist. */ | |
151 if (strcmp(key, "level") == 0) | |
1079
8f26ee9cc6dd
misc: unconditionnally add BSD->POSIX extensions
David Demelier <markand@malikania.fr>
parents:
1009
diff
changeset
|
152 irc_util_strlcpy(my_template_level, value, sizeof (my_template_level)); |
1009 | 153 else if (strcmp(key, "language") == 0) |
1079
8f26ee9cc6dd
misc: unconditionnally add BSD->POSIX extensions
David Demelier <markand@malikania.fr>
parents:
1009
diff
changeset
|
154 irc_util_strlcpy(my_template_language, value, sizeof (my_template_language)); |
1009 | 155 } |
156 | |
157 /* | |
158 * event | |
159 * ---------------------------------------------------------------------- | |
160 * | |
161 * This function is called when an event has been received. The parameter ev | |
162 * contains a union with every possible supported event, the plugin must not | |
163 * modify it. | |
164 * | |
165 * Use the ev->type enumeration to read the appropriate union member. | |
166 */ | |
167 | |
168 void | |
169 example_event(const struct irc_event *ev) | |
170 { | |
171 /* Simply echo back in case of message. */ | |
172 if (ev->type == IRC_EVENT_MESSAGE) | |
173 irc_server_message(ev->server, ev->message.channel, ev->message.message); | |
174 } |