Branch data Line data Source code
1 : : /*-
2 : : * Copyright (c) 2011-2013 Baptiste Daroussin <bapt@FreeBSD.org>
3 : : * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
4 : : * Copyright (c) 2015 Matthew Seaman <matthew@FreeBSD.org>
5 : : * All rights reserved.
6 : : *
7 : : * Redistribution and use in source and binary forms, with or without
8 : : * modification, are permitted provided that the following conditions
9 : : * are met:
10 : : * 1. Redistributions of source code must retain the above copyright
11 : : * notice, this list of conditions and the following disclaimer
12 : : * in this position and unchanged.
13 : : * 2. Redistributions in binary form must reproduce the above copyright
14 : : * notice, this list of conditions and the following disclaimer in the
15 : : * documentation and/or other materials provided with the distribution.
16 : : *
17 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
18 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 : : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
21 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 : : */
28 : :
29 : : #include <errno.h>
30 : : #include <string.h>
31 : : #include <syslog.h>
32 : : #include <xstring.h>
33 : :
34 : : #include "pkg.h"
35 : : #include "private/pkg.h"
36 : : #include "private/event.h"
37 : :
38 : : static pkg_event_cb _cb = NULL;
39 : : static void *_data = NULL;
40 : :
41 : : static char *
42 : 0 : buf_json_escape(const char *str)
43 : : {
44 : 0 : xstring *buf = xstring_new();
45 : :
46 [ # # # # ]: 0 : while (str != NULL && *str != '\0') {
47 [ # # # # ]: 0 : if (*str == '"' || *str == '\\')
48 : 0 : fputc('\\', buf->fp);
49 : 0 : fputc(*str, buf->fp);
50 : 0 : str++;
51 : : }
52 : :
53 : 0 : return (xstring_get(buf));
54 : : }
55 : :
56 : : static void
57 : 26289 : pipeevent(struct pkg_event *ev)
58 : : {
59 : : int i;
60 : 26289 : struct pkg_dep *dep = NULL;
61 : : xstring *msg;
62 : : struct pkg_event_conflict *cur_conflict;
63 [ - + ]: 26289 : if (ctx.eventpipe < 0)
64 : 26289 : return;
65 : :
66 : 0 : msg = xstring_new();
67 : :
68 [ # # # # : 0 : switch(ev->type) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
69 : : case PKG_EVENT_ERRNO:
70 : 0 : fprintf(msg->fp, "{ \"type\": \"ERROR\", "
71 : : "\"data\": {"
72 : : "\"msg\": \"%s(%s): %s\","
73 : : "\"errno\": %d}}",
74 : 0 : buf_json_escape(ev->e_errno.func),
75 : 0 : buf_json_escape(ev->e_errno.arg),
76 : 0 : buf_json_escape(strerror(ev->e_errno.no)),
77 : 0 : ev->e_errno.no);
78 : 0 : break;
79 : : case PKG_EVENT_ERROR:
80 : 0 : fprintf(msg->fp, "{ \"type\": \"ERROR\", "
81 : : "\"data\": {\"msg\": \"%s\"}}",
82 : 0 : buf_json_escape(ev->e_pkg_error.msg));
83 : 0 : break;
84 : : case PKG_EVENT_NOTICE:
85 : 0 : fprintf(msg->fp, "{ \"type\": \"NOTICE\", "
86 : : "\"data\": {\"msg\": \"%s\"}}",
87 : 0 : buf_json_escape(ev->e_pkg_notice.msg));
88 : 0 : break;
89 : : case PKG_EVENT_DEVELOPER_MODE:
90 : 0 : fprintf(msg->fp, "{ \"type\": \"ERROR\", "
91 : : "\"data\": {\"msg\": \"DEVELOPER_MODE: %s\"}}",
92 : 0 : buf_json_escape(ev->e_pkg_error.msg));
93 : 0 : break;
94 : : case PKG_EVENT_UPDATE_ADD:
95 : 0 : fprintf(msg->fp, "{ \"type\": \"INFO_UPDATE_ADD\", "
96 : : "\"data\": { "
97 : : "\"fetched\": %d, "
98 : : "\"total\": %d"
99 : : "}}",
100 : 0 : ev->e_upd_add.done,
101 : 0 : ev->e_upd_add.total
102 : : );
103 : 0 : break;
104 : : case PKG_EVENT_UPDATE_REMOVE:
105 : 0 : fprintf(msg->fp, "{ \"type\": \"INFO_UPDATE_REMOVE\", "
106 : : "\"data\": { "
107 : : "\"fetched\": %d, "
108 : : "\"total\": %d"
109 : : "}}",
110 : 0 : ev->e_upd_remove.done,
111 : 0 : ev->e_upd_remove.total
112 : : );
113 : 0 : break;
114 : : case PKG_EVENT_FETCH_BEGIN:
115 : 0 : fprintf(msg->fp, "{ \"type\": \"INFO_FETCH_BEGIN\", "
116 : : "\"data\": { "
117 : : "\"url\": \"%s\" "
118 : : "}}",
119 : 0 : buf_json_escape(ev->e_fetching.url)
120 : : );
121 : 0 : break;
122 : : case PKG_EVENT_FETCH_FINISHED:
123 : 0 : fprintf(msg->fp, "{ \"type\": \"INFO_FETCH_FINISHED\", "
124 : : "\"data\": { "
125 : : "\"url\": \"%s\" "
126 : : "}}",
127 : 0 : buf_json_escape(ev->e_fetching.url)
128 : : );
129 : 0 : break;
130 : : case PKG_EVENT_INSTALL_BEGIN:
131 : 0 : pkg_fprintf(msg->fp, "{ \"type\": \"INFO_INSTALL_BEGIN\", "
132 : : "\"data\": { "
133 : : "\"pkgname\": \"%n\", "
134 : : "\"pkgversion\": \"%v\""
135 : 0 : "}}", ev->e_install_begin.pkg, ev->e_install_begin.pkg);
136 : 0 : break;
137 : : case PKG_EVENT_EXTRACT_BEGIN:
138 : 0 : pkg_fprintf(msg->fp, "{ \"type\": \"INFO_EXTRACT_BEGIN\", "
139 : : "\"data\": { "
140 : : "\"pkgname\": \"%n\", "
141 : : "\"pkgversion\": \"%v\""
142 : 0 : "}}", ev->e_extract_begin.pkg, ev->e_extract_begin.pkg);
143 : 0 : break;
144 : : case PKG_EVENT_EXTRACT_FINISHED:
145 : 0 : pkg_fprintf(msg->fp, "{ \"type\": \"INFO_EXTRACT_FINISHED\", "
146 : : "\"data\": { "
147 : : "\"pkgname\": \"%n\", "
148 : : "\"pkgversion\": \"%v\""
149 : 0 : "}}", ev->e_extract_finished.pkg, ev->e_extract_finished.pkg);
150 : 0 : break;
151 : : case PKG_EVENT_INSTALL_FINISHED:
152 : 0 : pkg_fprintf(msg->fp, "{ \"type\": \"INFO_INSTALL_FINISHED\", "
153 : : "\"data\": { "
154 : : "\"pkgname\": \"%n\", "
155 : : "\"pkgversion\": \"%v\", "
156 : : "\"message\": \"%S\""
157 : : "}}",
158 : 0 : ev->e_install_finished.pkg,
159 : 0 : ev->e_install_finished.pkg,
160 [ # # ]: 0 : ev->e_install_finished.pkg->message ?
161 : 0 : buf_json_escape(ev->e_install_finished.pkg->message->str) :
162 : : "");
163 : 0 : break;
164 : : case PKG_EVENT_INTEGRITYCHECK_BEGIN:
165 : 0 : fputs("{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", "
166 : 0 : "\"data\": {}}", msg->fp);
167 : 0 : break;
168 : : case PKG_EVENT_INTEGRITYCHECK_CONFLICT:
169 : 0 : fprintf(msg->fp, "{ \"type\": \"INFO_INTEGRITYCHECK_CONFLICT\","
170 : : "\"data\": { "
171 : : "\"pkguid\": \"%s\", "
172 : : "\"pkgpath\": \"%s\", "
173 : : "\"conflicts\": [",
174 : 0 : ev->e_integrity_conflict.pkg_uid,
175 : 0 : ev->e_integrity_conflict.pkg_path);
176 : 0 : cur_conflict = ev->e_integrity_conflict.conflicts;
177 [ # # ]: 0 : while (cur_conflict != NULL) {
178 [ # # ]: 0 : if (cur_conflict->next != NULL) {
179 : 0 : fprintf(msg->fp, "{\"uid\":\"%s\"},",
180 : 0 : cur_conflict->uid);
181 : 0 : }
182 : : else {
183 : 0 : fprintf(msg->fp, "{\"uid\":\"%s\"}",
184 : 0 : cur_conflict->uid);
185 : 0 : break;
186 : : }
187 : 0 : cur_conflict = cur_conflict->next;
188 : : }
189 : 0 : fputs("]}}", msg->fp);
190 : 0 : break;
191 : : case PKG_EVENT_INTEGRITYCHECK_FINISHED:
192 : 0 : fprintf(msg->fp, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", "
193 : : "\"data\": {\"conflicting\": %d}}",
194 : 0 : ev->e_integrity_finished.conflicting);
195 : 0 : break;
196 : : case PKG_EVENT_DEINSTALL_BEGIN:
197 : 0 : pkg_fprintf(msg->fp, "{ \"type\": \"INFO_DEINSTALL_BEGIN\", "
198 : : "\"data\": { "
199 : : "\"pkgname\": \"%n\", "
200 : : "\"pkgversion\": \"%v\""
201 : : "}}",
202 : 0 : ev->e_deinstall_begin.pkg,
203 : 0 : ev->e_deinstall_begin.pkg);
204 : 0 : break;
205 : : case PKG_EVENT_DEINSTALL_FINISHED:
206 : 0 : pkg_fprintf(msg->fp, "{ \"type\": \"INFO_DEINSTALL_FINISHED\", "
207 : : "\"data\": { "
208 : : "\"pkgname\": \"%n\", "
209 : : "\"pkgversion\": \"%v\""
210 : : "}}",
211 : 0 : ev->e_deinstall_finished.pkg,
212 : 0 : ev->e_deinstall_finished.pkg);
213 : 0 : break;
214 : : case PKG_EVENT_UPGRADE_BEGIN:
215 : 0 : pkg_fprintf(msg->fp, "{ \"type\": \"INFO_UPGRADE_BEGIN\", "
216 : : "\"data\": { "
217 : : "\"pkgname\": \"%n\", "
218 : : "\"pkgversion\": \"%v\" ,"
219 : : "\"pkgnewversion\": \"%v\""
220 : : "}}",
221 : 0 : ev->e_upgrade_begin.o,
222 : 0 : ev->e_upgrade_begin.o,
223 : 0 : ev->e_upgrade_begin.n);
224 : 0 : break;
225 : : case PKG_EVENT_UPGRADE_FINISHED:
226 : 0 : pkg_fprintf(msg->fp, "{ \"type\": \"INFO_UPGRADE_FINISHED\", "
227 : : "\"data\": { "
228 : : "\"pkgname\": \"%n\", "
229 : : "\"pkgversion\": \"%v\" ,"
230 : : "\"pkgnewversion\": \"%v\""
231 : : "}}",
232 : 0 : ev->e_upgrade_finished.o,
233 : 0 : ev->e_upgrade_finished.o,
234 : 0 : ev->e_upgrade_finished.n);
235 : 0 : break;
236 : : case PKG_EVENT_LOCKED:
237 : 0 : pkg_fprintf(msg->fp, "{ \"type\": \"ERROR_LOCKED\", "
238 : : "\"data\": { "
239 : : "\"pkgname\": \"%n\", "
240 : : "\"pkgversion\": \"%n\""
241 : : "}}",
242 : 0 : ev->e_locked.pkg,
243 : 0 : ev->e_locked.pkg);
244 : 0 : break;
245 : : case PKG_EVENT_REQUIRED:
246 : 0 : pkg_fprintf(msg->fp, "{ \"type\": \"ERROR_REQUIRED\", "
247 : : "\"data\": { "
248 : : "\"pkgname\": \"%n\", "
249 : : "\"pkgversion\": \"%v\", "
250 : : "\"force\": %S, "
251 : : "\"required_by\": [",
252 : 0 : ev->e_required.pkg,
253 : 0 : ev->e_required.pkg,
254 : 0 : ev->e_required.force == 1 ? "true": "false");
255 [ # # ]: 0 : while (pkg_rdeps(ev->e_required.pkg, &dep) == EPKG_OK)
256 : 0 : fprintf(msg->fp, "{ \"pkgname\": \"%s\", "
257 : : "\"pkgversion\": \"%s\" }, ",
258 : 0 : dep->name, dep->version);
259 : 0 : int c = 0;
260 : 0 : ungetc(c, msg->fp);
261 : 0 : ungetc(c, msg->fp);
262 : 0 : fputs("]}}", msg->fp);
263 : 0 : break;
264 : : case PKG_EVENT_ALREADY_INSTALLED:
265 : 0 : pkg_fprintf(msg->fp, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", "
266 : : "\"data\": { "
267 : : "\"pkgname\": \"%n\", "
268 : : "\"pkgversion\": \"%v\""
269 : : "}}",
270 : 0 : ev->e_already_installed.pkg,
271 : 0 : ev->e_already_installed.pkg);
272 : 0 : break;
273 : : case PKG_EVENT_MISSING_DEP:
274 : 0 : fprintf(msg->fp, "{ \"type\": \"ERROR_MISSING_DEP\", "
275 : : "\"data\": { "
276 : : "\"depname\": \"%s\", "
277 : : "\"depversion\": \"%s\""
278 : : "}}" ,
279 : 0 : ev->e_missing_dep.dep->name,
280 : 0 : ev->e_missing_dep.dep->version);
281 : 0 : break;
282 : : case PKG_EVENT_NOREMOTEDB:
283 : 0 : fprintf(msg->fp, "{ \"type\": \"ERROR_NOREMOTEDB\", "
284 : : "\"data\": { "
285 : : "\"url\": \"%s\" "
286 : : "}}" ,
287 : 0 : ev->e_remotedb.repo);
288 : 0 : break;
289 : : case PKG_EVENT_NOLOCALDB:
290 : 0 : fputs("{ \"type\": \"ERROR_NOLOCALDB\", \"data\": {}} ",
291 : 0 : msg->fp);
292 : 0 : break;
293 : : case PKG_EVENT_NEWPKGVERSION:
294 : 0 : fputs("{ \"type\": \"INFO_NEWPKGVERSION\", \"data\": {}} ",
295 : 0 : msg->fp);
296 : 0 : break;
297 : : case PKG_EVENT_FILE_MISMATCH:
298 : 0 : pkg_fprintf(msg->fp, "{ \"type\": \"ERROR_FILE_MISMATCH\", "
299 : : "\"data\": { "
300 : : "\"pkgname\": \"%n\", "
301 : : "\"pkgversion\": \"%v\", "
302 : : "\"path\": \"%S\""
303 : : "}}",
304 : 0 : ev->e_file_mismatch.pkg,
305 : 0 : ev->e_file_mismatch.pkg,
306 : 0 : buf_json_escape(ev->e_file_mismatch.file->path));
307 : 0 : break;
308 : : case PKG_EVENT_PLUGIN_ERRNO:
309 : 0 : fprintf(msg->fp, "{ \"type\": \"ERROR_PLUGIN\", "
310 : : "\"data\": {"
311 : : "\"plugin\": \"%s\", "
312 : : "\"msg\": \"%s(%s): %s\","
313 : : "\"errno\": %d"
314 : : "}}",
315 : 0 : pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME),
316 : 0 : buf_json_escape(ev->e_plugin_errno.func),
317 : 0 : buf_json_escape(ev->e_plugin_errno.arg),
318 : 0 : buf_json_escape(strerror(ev->e_plugin_errno.no)),
319 : 0 : ev->e_plugin_errno.no);
320 : 0 : break;
321 : : case PKG_EVENT_PLUGIN_ERROR:
322 : 0 : fprintf(msg->fp, "{ \"type\": \"ERROR_PLUGIN\", "
323 : : "\"data\": {"
324 : : "\"plugin\": \"%s\", "
325 : : "\"msg\": \"%s\""
326 : : "}}",
327 : 0 : pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME),
328 : 0 : buf_json_escape(ev->e_plugin_error.msg));
329 : 0 : break;
330 : : case PKG_EVENT_PLUGIN_INFO:
331 : 0 : fprintf(msg->fp, "{ \"type\": \"INFO_PLUGIN\", "
332 : : "\"data\": {"
333 : : "\"plugin\": \"%s\", "
334 : : "\"msg\": \"%s\""
335 : : "}}",
336 : 0 : pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME),
337 : 0 : buf_json_escape(ev->e_plugin_info.msg));
338 : 0 : break;
339 : : case PKG_EVENT_INCREMENTAL_UPDATE:
340 : 0 : fprintf(msg->fp, "{ \"type\": \"INFO_INCREMENTAL_UPDATE\", "
341 : : "\"data\": {"
342 : : "\"name\": \"%s\", "
343 : : "\"processed\": %d"
344 : 0 : "}}", ev->e_incremental_update.reponame,
345 : 0 : ev->e_incremental_update.processed);
346 : 0 : break;
347 : : case PKG_EVENT_QUERY_YESNO:
348 : 0 : fprintf(msg->fp, "{ \"type\": \"QUERY_YESNO\", "
349 : : "\"data\": {"
350 : : "\"msg\": \"%s\","
351 : : "\"default\": \"%d\""
352 : 0 : "}}", ev->e_query_yesno.msg,
353 : 0 : ev->e_query_yesno.deft);
354 : 0 : break;
355 : : case PKG_EVENT_QUERY_SELECT:
356 : 0 : fprintf(msg->fp, "{ \"type\": \"QUERY_SELECT\", "
357 : : "\"data\": {"
358 : : "\"msg\": \"%s\","
359 : : "\"ncnt\": \"%d\","
360 : : "\"default\": \"%d\","
361 : : "\"items\": ["
362 : 0 : , ev->e_query_select.msg,
363 : 0 : ev->e_query_select.ncnt,
364 : 0 : ev->e_query_select.deft);
365 [ # # ]: 0 : for (i = 0; i < ev->e_query_select.ncnt - 1; i++)
366 : : {
367 : 0 : fprintf(msg->fp, "{ \"text\": \"%s\" },",
368 : 0 : ev->e_query_select.items[i]);
369 : 0 : }
370 : 0 : fprintf(msg->fp, "{ \"text\": \"%s\" } ] }}",
371 : 0 : ev->e_query_select.items[i]);
372 : 0 : break;
373 : : case PKG_EVENT_PROGRESS_START:
374 : 0 : fputs("{ \"type\": \"INFO_PROGRESS_START\", \"data\": {}}",
375 : 0 : msg->fp);
376 : 0 : break;
377 : : case PKG_EVENT_PROGRESS_TICK:
378 : 0 : fprintf(msg->fp, "{ \"type\": \"INFO_PROGRESS_TICK\", "
379 : : "\"data\": { \"current\": %jd, \"total\" : %jd}}",
380 : 0 : (intmax_t)ev->e_progress_tick.current,
381 : 0 : (intmax_t)ev->e_progress_tick.total);
382 : 0 : break;
383 : : case PKG_EVENT_TRIGGERS_BEGIN:
384 : 0 : fputs("{ \"type\": \"INFO_TRIGGERS_BEGIN\", \"data\": {}}",
385 : 0 : msg->fp);
386 : 0 : break;
387 : : case PKG_EVENT_TRIGGERS_FINISHED:
388 : 0 : fputs("{ \"type\": \"INFO_TRIGGERS_FINISHED\", \"data\": {}}",
389 : 0 : msg->fp);
390 : 0 : break;
391 : : case PKG_EVENT_TRIGGER:
392 : 0 : fprintf(msg->fp, "{ \"type\": \"INFO_TRIGGER\", \"data\": { "
393 : : "\"cleanup\": %s, \"name\": \"%s\" }}",
394 : 0 : ev->e_trigger.cleanup ? "true" : "false",
395 : 0 : ev->e_trigger.name);
396 : : case PKG_EVENT_BACKUP:
397 : : case PKG_EVENT_RESTORE:
398 : 0 : break;
399 : : default:
400 : 0 : break;
401 : : }
402 : 0 : fflush(msg->fp);
403 : 0 : dprintf(ctx.eventpipe, "%s\n", msg->buf);
404 : 0 : xstring_free(msg);
405 : 26289 : }
406 : :
407 : : void
408 : 3527 : pkg_event_register(pkg_event_cb cb, void *data)
409 : : {
410 : 3527 : _cb = cb;
411 : 3527 : _data = data;
412 : 3527 : }
413 : :
414 : : static int
415 : 26289 : pkg_emit_event(struct pkg_event *ev)
416 : : {
417 : 26289 : int ret = 0;
418 : 26289 : pkg_plugins_hook_run(PKG_PLUGIN_HOOK_EVENT, ev, NULL);
419 [ + + ]: 26289 : if (_cb != NULL)
420 : 26198 : ret = _cb(_data, ev);
421 : 26289 : pipeevent(ev);
422 : 26289 : return (ret);
423 : : }
424 : :
425 : : void
426 : 621 : pkg_emit_error(const char *fmt, ...)
427 : : {
428 : : struct pkg_event ev;
429 : : va_list ap;
430 : :
431 : 621 : ev.type = PKG_EVENT_ERROR;
432 : :
433 : 621 : va_start(ap, fmt);
434 : 621 : vasprintf(&ev.e_pkg_error.msg, fmt, ap);
435 : 621 : va_end(ap);
436 : :
437 : 621 : pkg_emit_event(&ev);
438 : 621 : free(ev.e_pkg_error.msg);
439 : 621 : }
440 : :
441 : : void
442 : 20 : pkg_emit_notice(const char *fmt, ...)
443 : : {
444 : : struct pkg_event ev;
445 : : va_list ap;
446 : :
447 : 20 : ev.type = PKG_EVENT_NOTICE;
448 : :
449 : 20 : va_start(ap, fmt);
450 : 20 : vasprintf(&ev.e_pkg_notice.msg, fmt, ap);
451 : 20 : va_end(ap);
452 : :
453 : 20 : pkg_emit_event(&ev);
454 : 20 : free(ev.e_pkg_error.msg);
455 : 20 : }
456 : :
457 : : void
458 : 0 : pkg_emit_developer_mode(const char *fmt, ...)
459 : : {
460 : : struct pkg_event ev;
461 : : va_list ap;
462 : :
463 : 0 : ev.type = PKG_EVENT_DEVELOPER_MODE;
464 : :
465 : 0 : va_start(ap, fmt);
466 : 0 : vasprintf(&ev.e_pkg_error.msg, fmt, ap);
467 : 0 : va_end(ap);
468 : :
469 : 0 : pkg_emit_event(&ev);
470 : 0 : free(ev.e_pkg_error.msg);
471 : 0 : }
472 : :
473 : : void
474 : 0 : pkg_emit_errno(const char *func, const char *arg)
475 : : {
476 : : struct pkg_event ev;
477 : :
478 : 0 : ev.type = PKG_EVENT_ERRNO;
479 : 0 : ev.e_errno.func = func;
480 : 0 : ev.e_errno.arg = arg;
481 : 0 : ev.e_errno.no = errno;
482 : :
483 : 0 : pkg_emit_event(&ev);
484 : 0 : }
485 : :
486 : : void
487 : 0 : pkg_emit_already_installed(struct pkg *p)
488 : : {
489 : : struct pkg_event ev;
490 : :
491 : 0 : ev.type = PKG_EVENT_ALREADY_INSTALLED;
492 : 0 : ev.e_already_installed.pkg = p;
493 : :
494 : 0 : pkg_emit_event(&ev);
495 : 0 : }
496 : :
497 : : void
498 : 496 : pkg_emit_fetch_begin(const char *url)
499 : : {
500 : : struct pkg_event ev;
501 : :
502 : 496 : ev.type = PKG_EVENT_FETCH_BEGIN;
503 : 496 : ev.e_fetching.url = url;
504 : :
505 : 496 : pkg_emit_event(&ev);
506 : 496 : }
507 : :
508 : : void
509 : 496 : pkg_emit_fetch_finished(const char *url)
510 : : {
511 : : struct pkg_event ev;
512 : :
513 : 496 : ev.type = PKG_EVENT_FETCH_FINISHED;
514 : 496 : ev.e_fetching.url = url;
515 : :
516 : 496 : pkg_emit_event(&ev);
517 : 496 : }
518 : :
519 : : void
520 : 0 : pkg_emit_update_remove(int total, int done)
521 : : {
522 : : struct pkg_event ev;
523 : :
524 : 0 : ev.type = PKG_EVENT_UPDATE_REMOVE;
525 : 0 : ev.e_upd_remove.total = total;
526 : 0 : ev.e_upd_remove.done = done;
527 : :
528 : 0 : pkg_emit_event(&ev);
529 : 0 : }
530 : :
531 : :
532 : : void
533 : 0 : pkg_emit_update_add(int total, int done)
534 : : {
535 : : struct pkg_event ev;
536 : :
537 : 0 : ev.type = PKG_EVENT_UPDATE_ADD;
538 : 0 : ev.e_upd_add.total = total;
539 : 0 : ev.e_upd_add.done = done;
540 : :
541 : 0 : pkg_emit_event(&ev);
542 : 0 : }
543 : :
544 : : void
545 : 983 : pkg_emit_install_begin(struct pkg *p)
546 : : {
547 : : struct pkg_event ev;
548 : :
549 : 983 : ev.type = PKG_EVENT_INSTALL_BEGIN;
550 : 983 : ev.e_install_begin.pkg = p;
551 : :
552 : 983 : pkg_emit_event(&ev);
553 : 983 : }
554 : :
555 : : void
556 : 936 : pkg_emit_install_finished(struct pkg *p, struct pkg *old)
557 : : {
558 : : struct pkg_event ev;
559 : 936 : bool syslog_enabled = false;
560 : :
561 : 936 : ev.type = PKG_EVENT_INSTALL_FINISHED;
562 : 936 : ev.e_install_finished.pkg = p;
563 : 936 : ev.e_install_finished.old = old;
564 : :
565 : 936 : syslog_enabled = pkg_object_bool(pkg_config_get("SYSLOG"));
566 [ - + ]: 936 : if (syslog_enabled) {
567 : 936 : syslog(LOG_NOTICE, "%s-%s installed",
568 : 936 : p->name, p->version);
569 : 936 : }
570 : :
571 : 936 : pkg_emit_event(&ev);
572 : 936 : }
573 : :
574 : : void
575 : 203 : pkg_emit_add_deps_begin(struct pkg *p)
576 : : {
577 : : struct pkg_event ev;
578 : :
579 : 203 : ev.type = PKG_EVENT_ADD_DEPS_BEGIN;
580 : 203 : ev.e_add_deps_begin.pkg = p;
581 : :
582 : 203 : pkg_emit_event(&ev);
583 : 203 : }
584 : :
585 : : void
586 : 203 : pkg_emit_add_deps_finished(struct pkg *p)
587 : : {
588 : : struct pkg_event ev;
589 : :
590 : 203 : ev.type = PKG_EVENT_ADD_DEPS_FINISHED;
591 : 203 : ev.e_add_deps_finished.pkg = p;
592 : :
593 : 203 : pkg_emit_event(&ev);
594 : 203 : }
595 : :
596 : : void
597 : 440 : pkg_emit_extract_begin(struct pkg *p)
598 : : {
599 : : struct pkg_event ev;
600 : :
601 : 440 : ev.type = PKG_EVENT_EXTRACT_BEGIN;
602 : 440 : ev.e_extract_begin.pkg = p;
603 : :
604 : 440 : pkg_emit_event(&ev);
605 : 440 : }
606 : :
607 : : void
608 : 440 : pkg_emit_extract_finished(struct pkg *p)
609 : : {
610 : : struct pkg_event ev;
611 : :
612 : 440 : ev.type = PKG_EVENT_EXTRACT_FINISHED;
613 : 440 : ev.e_extract_finished.pkg = p;
614 : :
615 : 440 : pkg_emit_event(&ev);
616 : 440 : }
617 : :
618 : : void
619 : 93 : pkg_emit_delete_files_begin(struct pkg *p)
620 : : {
621 : : struct pkg_event ev;
622 : :
623 : 93 : ev.type = PKG_EVENT_DELETE_FILES_BEGIN;
624 : 93 : ev.e_delete_files_begin.pkg = p;
625 : :
626 : 93 : pkg_emit_event(&ev);
627 : 93 : }
628 : :
629 : : void
630 : 93 : pkg_emit_delete_files_finished(struct pkg *p)
631 : : {
632 : : struct pkg_event ev;
633 : :
634 : 93 : ev.type = PKG_EVENT_DELETE_FILES_FINISHED;
635 : 93 : ev.e_delete_files_finished.pkg = p;
636 : :
637 : 93 : pkg_emit_event(&ev);
638 : 93 : }
639 : :
640 : : void
641 : 636 : pkg_emit_integritycheck_begin(void)
642 : : {
643 : : struct pkg_event ev;
644 : 636 : ev.type = PKG_EVENT_INTEGRITYCHECK_BEGIN;
645 : :
646 : 636 : pkg_emit_event(&ev);
647 : 636 : }
648 : :
649 : : void
650 : 636 : pkg_emit_integritycheck_finished(int conflicting)
651 : : {
652 : : struct pkg_event ev;
653 : 636 : ev.type = PKG_EVENT_INTEGRITYCHECK_FINISHED;
654 : 636 : ev.e_integrity_finished.conflicting = conflicting;
655 : :
656 : 636 : pkg_emit_event(&ev);
657 : 636 : }
658 : :
659 : : void
660 : 0 : pkg_emit_integritycheck_conflict(const char *uid,
661 : : const char *path, struct pkg_event_conflict *conflicts)
662 : : {
663 : : struct pkg_event ev;
664 : 0 : ev.type = PKG_EVENT_INTEGRITYCHECK_CONFLICT;
665 : 0 : ev.e_integrity_conflict.pkg_uid = uid;
666 : 0 : ev.e_integrity_conflict.pkg_path = path;
667 : 0 : ev.e_integrity_conflict.conflicts = conflicts;
668 : :
669 : 0 : pkg_emit_event(&ev);
670 : 0 : }
671 : :
672 : : void
673 : 172 : pkg_emit_deinstall_begin(struct pkg *p)
674 : : {
675 : : struct pkg_event ev;
676 : :
677 : 172 : ev.type = PKG_EVENT_DEINSTALL_BEGIN;
678 : 172 : ev.e_deinstall_begin.pkg = p;
679 : :
680 : 172 : pkg_emit_event(&ev);
681 : 172 : }
682 : :
683 : : void
684 : 172 : pkg_emit_deinstall_finished(struct pkg *p)
685 : : {
686 : : struct pkg_event ev;
687 : 172 : bool syslog_enabled = false;
688 : :
689 : 172 : ev.type = PKG_EVENT_DEINSTALL_FINISHED;
690 : 172 : ev.e_deinstall_finished.pkg = p;
691 : :
692 : 172 : syslog_enabled = pkg_object_bool(pkg_config_get("SYSLOG"));
693 [ - + ]: 172 : if (syslog_enabled) {
694 : 172 : syslog(LOG_NOTICE, "%s-%s deinstalled",
695 : 172 : p->name, p->version);
696 : 172 : }
697 : :
698 : 172 : pkg_emit_event(&ev);
699 : 172 : }
700 : :
701 : : void
702 : 132 : pkg_emit_upgrade_begin(struct pkg *new, struct pkg *old)
703 : : {
704 : : struct pkg_event ev;
705 : :
706 : 132 : ev.type = PKG_EVENT_UPGRADE_BEGIN;
707 : 132 : ev.e_upgrade_begin.n = new;
708 : 132 : ev.e_upgrade_begin.o = old;
709 : :
710 : 132 : pkg_emit_event(&ev);
711 : 132 : }
712 : :
713 : : void
714 : 132 : pkg_emit_upgrade_finished(struct pkg *new, struct pkg *old)
715 : : {
716 : : struct pkg_event ev;
717 : 132 : bool syslog_enabled = false;
718 : :
719 : 132 : ev.type = PKG_EVENT_UPGRADE_FINISHED;
720 : 132 : ev.e_upgrade_finished.n = new;
721 : 132 : ev.e_upgrade_finished.o = old;
722 : :
723 : 132 : syslog_enabled = pkg_object_bool(pkg_config_get("SYSLOG"));
724 [ - + ]: 132 : if (syslog_enabled) {
725 : 132 : const char *actions[] = {
726 : : [PKG_DOWNGRADE] = "downgraded",
727 : : [PKG_REINSTALL] = "reinstalled",
728 : : [PKG_UPGRADE] = "upgraded",
729 : : };
730 : : pkg_change_t action;
731 : :
732 : 132 : action = pkg_version_change_between(new, old);
733 : 132 : syslog(LOG_NOTICE, "%s %s: %s %s %s ",
734 : 132 : new->name, actions[action],
735 [ - + ]: 132 : old->version != NULL ? old->version : new->version,
736 : 132 : old->version != NULL ? "->" : "",
737 [ - + ]: 132 : old->version != NULL ? new->version : "");
738 : 132 : }
739 : :
740 : 132 : pkg_emit_event(&ev);
741 : 132 : }
742 : :
743 : : void
744 : 65 : pkg_emit_missing_dep(struct pkg *p, struct pkg_dep *d)
745 : : {
746 : : struct pkg_event ev;
747 : :
748 : 65 : ev.type = PKG_EVENT_MISSING_DEP;
749 : 65 : ev.e_missing_dep.pkg = p;
750 : 65 : ev.e_missing_dep.dep = d;
751 : :
752 : 65 : pkg_emit_event(&ev);
753 : 65 : }
754 : :
755 : : void
756 : 0 : pkg_emit_locked(struct pkg *p)
757 : : {
758 : : struct pkg_event ev;
759 : :
760 : 0 : ev.type = PKG_EVENT_LOCKED;
761 : 0 : ev.e_locked.pkg = p;
762 : :
763 : 0 : pkg_emit_event(&ev);
764 : 0 : }
765 : :
766 : : void
767 : 0 : pkg_emit_required(struct pkg *p, int force)
768 : : {
769 : : struct pkg_event ev;
770 : :
771 : 0 : ev.type = PKG_EVENT_REQUIRED;
772 : 0 : ev.e_required.pkg = p;
773 : 0 : ev.e_required.force = force;
774 : :
775 : 0 : pkg_emit_event(&ev);
776 : 0 : }
777 : :
778 : : void
779 : 0 : pkg_emit_nolocaldb(void)
780 : : {
781 : : struct pkg_event ev;
782 : 0 : ev.type = PKG_EVENT_NOLOCALDB;
783 : :
784 : 0 : pkg_emit_event(&ev);
785 : 0 : }
786 : :
787 : : void
788 : 0 : pkg_emit_noremotedb(const char *repo)
789 : : {
790 : : struct pkg_event ev;
791 : 0 : ev.type = PKG_EVENT_NOREMOTEDB;
792 : :
793 : 0 : ev.e_remotedb.repo = repo;
794 : :
795 : 0 : pkg_emit_event(&ev);
796 : 0 : }
797 : :
798 : : void
799 : 13 : pkg_emit_newpkgversion(void)
800 : : {
801 : : struct pkg_event ev;
802 : 13 : ev.type = PKG_EVENT_NEWPKGVERSION;
803 : :
804 : 13 : pkg_emit_event(&ev);
805 : 13 : }
806 : :
807 : : void
808 : 0 : pkg_emit_file_mismatch(struct pkg *pkg, struct pkg_file *f, const char *newsum)
809 : : {
810 : : struct pkg_event ev;
811 : 0 : ev.type = PKG_EVENT_FILE_MISMATCH;
812 : :
813 : 0 : ev.e_file_mismatch.pkg = pkg;
814 : 0 : ev.e_file_mismatch.file = f;
815 : 0 : ev.e_file_mismatch.newsum = newsum;
816 : :
817 : 0 : pkg_emit_event(&ev);
818 : 0 : }
819 : :
820 : : void
821 : 0 : pkg_emit_file_missing(struct pkg *pkg, struct pkg_file *f)
822 : : {
823 : : struct pkg_event ev;
824 : 0 : ev.type = PKG_EVENT_FILE_MISSING;
825 : :
826 : 0 : ev.e_file_missing.pkg = pkg;
827 : 0 : ev.e_file_missing.file = f;
828 : :
829 : 0 : pkg_emit_event(&ev);
830 : 0 : }
831 : :
832 : : void
833 : 0 : pkg_plugin_errno(struct pkg_plugin *p, const char *func, const char *arg)
834 : : {
835 : : struct pkg_event ev;
836 : :
837 : 0 : ev.type = PKG_EVENT_PLUGIN_ERRNO;
838 : 0 : ev.e_plugin_errno.plugin = p;
839 : 0 : ev.e_plugin_errno.func = func;
840 : 0 : ev.e_plugin_errno.arg = arg;
841 : 0 : ev.e_plugin_errno.no = errno;
842 : :
843 : 0 : pkg_emit_event(&ev);
844 : 0 : }
845 : :
846 : : void
847 : 0 : pkg_plugin_error(struct pkg_plugin *p, const char *fmt, ...)
848 : : {
849 : : struct pkg_event ev;
850 : : va_list ap;
851 : :
852 : 0 : ev.type = PKG_EVENT_PLUGIN_ERROR;
853 : 0 : ev.e_plugin_error.plugin = p;
854 : :
855 : 0 : va_start(ap, fmt);
856 : 0 : vasprintf(&ev.e_plugin_error.msg, fmt, ap);
857 : 0 : va_end(ap);
858 : :
859 : 0 : pkg_emit_event(&ev);
860 : 0 : free(ev.e_plugin_error.msg);
861 : 0 : }
862 : :
863 : : void
864 : 0 : pkg_plugin_info(struct pkg_plugin *p, const char *fmt, ...)
865 : : {
866 : : struct pkg_event ev;
867 : : va_list ap;
868 : :
869 : 0 : ev.type = PKG_EVENT_PLUGIN_INFO;
870 : 0 : ev.e_plugin_info.plugin = p;
871 : :
872 : 0 : va_start(ap, fmt);
873 : 0 : vasprintf(&ev.e_plugin_info.msg, fmt, ap);
874 : 0 : va_end(ap);
875 : :
876 : 0 : pkg_emit_event(&ev);
877 : 0 : free(ev.e_plugin_info.msg);
878 : 0 : }
879 : :
880 : : void
881 : 0 : pkg_emit_package_not_found(const char *p)
882 : : {
883 : : struct pkg_event ev;
884 : :
885 : 0 : ev.type = PKG_EVENT_NOT_FOUND;
886 : 0 : ev.e_not_found.pkg_name = p;
887 : :
888 : 0 : pkg_emit_event(&ev);
889 : 0 : }
890 : :
891 : : void
892 : 244 : pkg_emit_incremental_update(const char *reponame, int processed)
893 : : {
894 : : struct pkg_event ev;
895 : :
896 : 244 : ev.type = PKG_EVENT_INCREMENTAL_UPDATE;
897 : 244 : ev.e_incremental_update.reponame = reponame;
898 : 244 : ev.e_incremental_update.processed = processed;
899 : :
900 : 244 : pkg_emit_event(&ev);
901 : 244 : }
902 : :
903 : : bool
904 : 0 : pkg_emit_query_yesno(bool deft, const char *msg)
905 : : {
906 : : struct pkg_event ev;
907 : : int ret;
908 : :
909 : 0 : ev.type = PKG_EVENT_QUERY_YESNO;
910 : 0 : ev.e_query_yesno.msg = msg;
911 : 0 : ev.e_query_yesno.deft = deft;
912 : :
913 : 0 : ret = pkg_emit_event(&ev);
914 : 0 : return (ret ? true : false);
915 : : }
916 : :
917 : : int
918 : 0 : pkg_emit_query_select(const char *msg, const char **items, int ncnt, int deft)
919 : : {
920 : : struct pkg_event ev;
921 : : int ret;
922 : :
923 : 0 : ev.type = PKG_EVENT_QUERY_SELECT;
924 : 0 : ev.e_query_select.msg = msg;
925 : 0 : ev.e_query_select.items = items;
926 : 0 : ev.e_query_select.ncnt = ncnt;
927 : 0 : ev.e_query_select.deft = deft;
928 : :
929 : 0 : ret = pkg_emit_event(&ev);
930 : 0 : return ret;
931 : : }
932 : :
933 : : int
934 : 244 : pkg_emit_sandbox_get_string(pkg_sandbox_cb call, void *ud, char **str, int64_t *len)
935 : : {
936 : : struct pkg_event ev;
937 : : int ret;
938 : :
939 : 244 : ev.type = PKG_EVENT_SANDBOX_GET_STRING;
940 : 244 : ev.e_sandbox_call_str.call = call;
941 : 244 : ev.e_sandbox_call_str.userdata = ud;
942 : 244 : ev.e_sandbox_call_str.result = str;
943 : 244 : ev.e_sandbox_call_str.len = len;
944 : :
945 : 244 : ret = pkg_emit_event(&ev);
946 : 244 : return ret;
947 : : }
948 : :
949 : : int
950 : 20 : pkg_emit_sandbox_call(pkg_sandbox_cb call, int fd, void *ud)
951 : : {
952 : : struct pkg_event ev;
953 : : int ret;
954 : :
955 : 20 : ev.type = PKG_EVENT_SANDBOX_CALL;
956 : 20 : ev.e_sandbox_call.call = call;
957 : 20 : ev.e_sandbox_call.fd = fd;
958 : 20 : ev.e_sandbox_call.userdata = ud;
959 : :
960 : 20 : ret = pkg_emit_event(&ev);
961 : 20 : return ret;
962 : : }
963 : :
964 : : void
965 : 257181 : pkg_debug(int level, const char *fmt, ...)
966 : : {
967 : : struct pkg_event ev;
968 : : va_list ap;
969 : :
970 [ + + ]: 257181 : if (ctx.debug_level < level)
971 : 257093 : return;
972 : :
973 : 88 : ev.type = PKG_EVENT_DEBUG;
974 : 88 : ev.e_debug.level = level;
975 : 88 : va_start(ap, fmt);
976 : 88 : vasprintf(&ev.e_debug.msg, fmt, ap);
977 : 88 : va_end(ap);
978 : :
979 : 88 : pkg_emit_event(&ev);
980 : 88 : free(ev.e_debug.msg);
981 : 257181 : }
982 : :
983 : : void
984 : 0 : pkg_emit_backup(void)
985 : : {
986 : : struct pkg_event ev;
987 : :
988 : 0 : ev.type = PKG_EVENT_BACKUP;
989 : :
990 : 0 : pkg_emit_event(&ev);
991 : 0 : }
992 : :
993 : : void
994 : 0 : pkg_emit_restore(void)
995 : : {
996 : : struct pkg_event ev;
997 : :
998 : 0 : ev.type = PKG_EVENT_RESTORE;
999 : :
1000 : 0 : pkg_emit_event(&ev);
1001 : 0 : }
1002 : :
1003 : : void
1004 : 5127 : pkg_emit_progress_start(const char *fmt, ...)
1005 : : {
1006 : : struct pkg_event ev;
1007 : : va_list ap;
1008 : :
1009 : 5127 : ev.type = PKG_EVENT_PROGRESS_START;
1010 [ + + ]: 5127 : if (fmt != NULL) {
1011 : 4098 : va_start(ap, fmt);
1012 : 4098 : vasprintf(&ev.e_progress_start.msg, fmt, ap);
1013 : 4098 : va_end(ap);
1014 : 4098 : } else {
1015 : 1029 : ev.e_progress_start.msg = NULL;
1016 : : }
1017 : :
1018 : 5127 : pkg_emit_event(&ev);
1019 : 5127 : free(ev.e_progress_start.msg);
1020 : 5127 : }
1021 : :
1022 : : void
1023 : 8827 : pkg_emit_progress_tick(int64_t current, int64_t total)
1024 : : {
1025 : : struct pkg_event ev;
1026 : :
1027 : 8827 : ev.type = PKG_EVENT_PROGRESS_TICK;
1028 : 8827 : ev.e_progress_tick.current = current;
1029 : 8827 : ev.e_progress_tick.total = total;
1030 : :
1031 : 8827 : pkg_emit_event(&ev);
1032 : :
1033 : 8827 : }
1034 : :
1035 : : void
1036 : 906 : pkg_emit_new_action(void)
1037 : : {
1038 : : struct pkg_event ev;
1039 : :
1040 : 906 : ev.type = PKG_EVENT_NEW_ACTION;
1041 : :
1042 : 906 : pkg_emit_event(&ev);
1043 : 906 : }
1044 : :
1045 : : void
1046 : 112 : pkg_emit_message(const char *message)
1047 : : {
1048 : : struct pkg_event ev;
1049 : :
1050 : 112 : ev.type = PKG_EVENT_MESSAGE;
1051 : 112 : ev.e_pkg_message.msg = message;
1052 : 112 : pkg_emit_event(&ev);
1053 : 112 : }
1054 : :
1055 : : void
1056 : 696 : pkg_register_cleanup_callback(void (*cleanup_cb)(void *data), void *data)
1057 : : {
1058 : : struct pkg_event ev;
1059 : :
1060 : 696 : ev.type = PKG_EVENT_CLEANUP_CALLBACK_REGISTER;
1061 : 696 : ev.e_cleanup_callback.cleanup_cb = cleanup_cb;
1062 : 696 : ev.e_cleanup_callback.data = data;
1063 : 696 : pkg_emit_event(&ev);
1064 : 696 : }
1065 : :
1066 : : void
1067 : 867 : pkg_unregister_cleanup_callback(void (*cleanup_cb)(void *data), void *data)
1068 : : {
1069 : : struct pkg_event ev;
1070 : :
1071 : 867 : ev.type = PKG_EVENT_CLEANUP_CALLBACK_UNREGISTER;
1072 : 867 : ev.e_cleanup_callback.cleanup_cb = cleanup_cb;
1073 : 867 : ev.e_cleanup_callback.data = data;
1074 : 867 : pkg_emit_event(&ev);
1075 : 867 : }
1076 : :
1077 : : void
1078 : 60 : pkg_emit_conflicts(struct pkg *p1, struct pkg *p2, const char *path)
1079 : : {
1080 : : struct pkg_event ev;
1081 : :
1082 : 60 : ev.type = PKG_EVENT_CONFLICTS;
1083 : 60 : ev.e_conflicts.p1 = p1;
1084 : 60 : ev.e_conflicts.p2 = p2;
1085 : 60 : ev.e_conflicts.path = path;
1086 : 60 : pkg_emit_event(&ev);
1087 : 60 : }
1088 : :
1089 : : void
1090 : 1060 : pkg_emit_triggers_begin(void)
1091 : : {
1092 : : struct pkg_event ev;
1093 : :
1094 : 1060 : ev.type = PKG_EVENT_TRIGGERS_BEGIN;
1095 : :
1096 : 1060 : pkg_emit_event(&ev);
1097 : 1060 : }
1098 : :
1099 : : void
1100 : 1056 : pkg_emit_triggers_finished(void)
1101 : : {
1102 : : struct pkg_event ev;
1103 : :
1104 : 1056 : ev.type = PKG_EVENT_TRIGGERS_FINISHED;
1105 : :
1106 : 1056 : pkg_emit_event(&ev);
1107 : 1056 : }
1108 : :
1109 : : void
1110 : 32 : pkg_emit_trigger(const char *name, bool cleanup)
1111 : : {
1112 : : struct pkg_event ev;
1113 : :
1114 : 32 : ev.type = PKG_EVENT_TRIGGER;
1115 : 32 : ev.e_trigger.name = name;
1116 : 32 : ev.e_trigger.cleanup = cleanup;
1117 : :
1118 : 32 : }
|