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