comparison examples/sample-plugin.c @ 1009:637a98de3910

misc: add more examples
author David Demelier <markand@malikania.fr>
date Wed, 17 Feb 2021 19:45:00 +0100
parents
children 8f26ee9cc6dd
comparison
equal deleted inserted replaced
1008:201ddc487807 1009:637a98de3910
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)
142 strlcpy(my_option_level, value, sizeof (my_option_level));
143 else if (strcmp(key, "language") == 0)
144 strlcpy(my_option_language, value, sizeof (my_option_language));
145 }
146
147 void
148 example_set_template(const char *key)
149 {
150 /* Assuming my_template_* variable exist. */
151 if (strcmp(key, "level") == 0)
152 strlcpy(my_template_level, value, sizeof (my_template_level));
153 else if (strcmp(key, "language") == 0)
154 strlcpy(my_template_language, value, sizeof (my_template_language));
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 }