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