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