Пример #1
0
static void
pipeevent(struct pkg_event *ev)
{
	int i;
	struct pkg_dep *dep = NULL;
	struct sbuf *msg, *buf;
	struct pkg_event_conflict *cur_conflict;
	if (eventpipe < 0)
		return;

	msg = sbuf_new_auto();
	buf = sbuf_new_auto();

	switch(ev->type) {
	case PKG_EVENT_ERRNO:
		sbuf_printf(msg, "{ \"type\": \"ERROR\", "
		    "\"data\": {"
		    "\"msg\": \"%s(%s): %s\","
		    "\"errno\": %d}}",
		    sbuf_json_escape(buf, ev->e_errno.func),
		    sbuf_json_escape(buf, ev->e_errno.arg),
		    sbuf_json_escape(buf, strerror(ev->e_errno.no)),
		    ev->e_errno.no);
		break;
	case PKG_EVENT_ERROR:
		sbuf_printf(msg, "{ \"type\": \"ERROR\", "
		    "\"data\": {\"msg\": \"%s\"}}",
		    sbuf_json_escape(buf, ev->e_pkg_error.msg));
		break;
	case PKG_EVENT_NOTICE:
		sbuf_printf(msg, "{ \"type\": \"NOTICE\", "
		    "\"data\": {\"msg\": \"%s\"}}",
		    sbuf_json_escape(buf, ev->e_pkg_notice.msg));
		break;
	case PKG_EVENT_DEVELOPER_MODE:
		sbuf_printf(msg, "{ \"type\": \"ERROR\", "
		    "\"data\": {\"msg\": \"DEVELOPER_MODE: %s\"}}",
		    sbuf_json_escape(buf, ev->e_pkg_error.msg));
		break;
	case PKG_EVENT_UPDATE_ADD:
		sbuf_printf(msg, "{ \"type\": \"INFO_UPDATE_ADD\", "
		    "\"data\": { "
		    "\"fetched\": %d, "
		    "\"total\": %d"
		    "}}",
		    ev->e_upd_add.done,
		    ev->e_upd_add.total
		    );
		break;
	case PKG_EVENT_UPDATE_REMOVE:
		sbuf_printf(msg, "{ \"type\": \"INFO_UPDATE_REMOVE\", "
		    "\"data\": { "
		    "\"fetched\": %d, "
		    "\"total\": %d"
		    "}}",
		    ev->e_upd_remove.done,
		    ev->e_upd_remove.total
		    );
		break;
	case PKG_EVENT_FETCH_BEGIN:
		sbuf_printf(msg, "{ \"type\": \"INFO_FETCH_BEGIN\", "
		    "\"data\": { "
		    "\"url\": \"%s\" "
		    "}}",
		    sbuf_json_escape(buf, ev->e_fetching.url)
		    );
		break;
	case PKG_EVENT_FETCH_FINISHED:
		sbuf_printf(msg, "{ \"type\": \"INFO_FETCH_FINISHED\", "
		    "\"data\": { "
		    "\"url\": \"%s\" "
		    "}}",
		    sbuf_json_escape(buf, ev->e_fetching.url)
		    );
		break;
	case PKG_EVENT_INSTALL_BEGIN:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_BEGIN\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}", ev->e_install_begin.pkg, ev->e_install_begin.pkg);
		break;
	case PKG_EVENT_EXTRACT_BEGIN:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_EXTRACT_BEGIN\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}", ev->e_extract_begin.pkg, ev->e_extract_begin.pkg);
		break;
	case PKG_EVENT_EXTRACT_FINISHED:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_EXTRACT_FINISHED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}", ev->e_extract_finished.pkg, ev->e_extract_finished.pkg);
		break;
	case PKG_EVENT_INSTALL_FINISHED:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_FINISHED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\", "
		    "\"message\": \"%S\""
		    "}}",
		    ev->e_install_finished.pkg,
		    ev->e_install_finished.pkg,
			ev->e_install_finished.pkg->message ?
				sbuf_json_escape(buf, ev->e_install_finished.pkg->message->str) :
				"");
		break;
	case PKG_EVENT_INTEGRITYCHECK_BEGIN:
		sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", "
		    "\"data\": {}}");
		break;
	case PKG_EVENT_INTEGRITYCHECK_CONFLICT:
		sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_CONFLICT\","
			"\"data\": { "
			"\"pkguid\": \"%s\", "
			"\"pkgpath\": \"%s\", "
			"\"conflicts\": [",
			ev->e_integrity_conflict.pkg_uid,
			ev->e_integrity_conflict.pkg_path);
		cur_conflict = ev->e_integrity_conflict.conflicts;
		while (cur_conflict != NULL) {
			if (cur_conflict->next != NULL) {
				sbuf_printf(msg, "{\"uid\":\"%s\"},",
						cur_conflict->uid);
			}
			else {
				sbuf_printf(msg, "{\"uid\":\"%s\"}",
						cur_conflict->uid);
				break;
			}
			cur_conflict = cur_conflict->next;
		}
		sbuf_cat(msg, "]}}");
		break;
	case PKG_EVENT_INTEGRITYCHECK_FINISHED:
		sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", "
		    "\"data\": {\"conflicting\": %d}}",
		    ev->e_integrity_finished.conflicting);
		break;
	case PKG_EVENT_DEINSTALL_BEGIN:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_BEGIN\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}",
		    ev->e_deinstall_begin.pkg,
		    ev->e_deinstall_begin.pkg);
		break;
	case PKG_EVENT_DEINSTALL_FINISHED:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_FINISHED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}",
		    ev->e_deinstall_finished.pkg,
		    ev->e_deinstall_finished.pkg);
		break;
	case PKG_EVENT_UPGRADE_BEGIN:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_BEGIN\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\" ,"
		    "\"pkgnewversion\": \"%v\""
		    "}}",
		    ev->e_upgrade_begin.o,
		    ev->e_upgrade_begin.o,
		    ev->e_upgrade_begin.n);
		break;
	case PKG_EVENT_UPGRADE_FINISHED:
		pkg_sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_FINISHED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\" ,"
		    "\"pkgnewversion\": \"%v\""
		    "}}",
		    ev->e_upgrade_finished.o,
		    ev->e_upgrade_finished.o,
		    ev->e_upgrade_finished.n);
		break;
	case PKG_EVENT_LOCKED:
		pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_LOCKED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%n\""
		    "}}",
		    ev->e_locked.pkg,
		    ev->e_locked.pkg);
		break;
	case PKG_EVENT_REQUIRED:
		pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_REQUIRED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\", "
		    "\"force\": %S, "
		    "\"required_by\": [",
		    ev->e_required.pkg,
		    ev->e_required.pkg,
		    ev->e_required.force == 1 ? "true": "false");
		while (pkg_rdeps(ev->e_required.pkg, &dep) == EPKG_OK)
			sbuf_printf(msg, "{ \"pkgname\": \"%s\", "
			    "\"pkgversion\": \"%s\" }, ",
			    dep->name, dep->version);
		sbuf_setpos(msg, sbuf_len(msg) - 2);
		sbuf_cat(msg, "]}}");
		break;
	case PKG_EVENT_ALREADY_INSTALLED:
		pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\""
		    "}}",
		    ev->e_already_installed.pkg,
		    ev->e_already_installed.pkg);
		break;
	case PKG_EVENT_MISSING_DEP:
		sbuf_printf(msg, "{ \"type\": \"ERROR_MISSING_DEP\", "
		    "\"data\": { "
		    "\"depname\": \"%s\", "
		    "\"depversion\": \"%s\""
		    "}}" ,
		    ev->e_missing_dep.dep->name,
		    ev->e_missing_dep.dep->version);
		break;
	case PKG_EVENT_NOREMOTEDB:
		sbuf_printf(msg, "{ \"type\": \"ERROR_NOREMOTEDB\", "
		    "\"data\": { "
		    "\"url\": \"%s\" "
		    "}}" ,
		    ev->e_remotedb.repo);
		break;
	case PKG_EVENT_NOLOCALDB:
		sbuf_printf(msg, "{ \"type\": \"ERROR_NOLOCALDB\", "
		    "\"data\": {} ");
		break;
	case PKG_EVENT_NEWPKGVERSION:
		sbuf_printf(msg, "{ \"type\": \"INFO_NEWPKGVERSION\", "
		    "\"data\": {} ");
		break;
	case PKG_EVENT_FILE_MISMATCH:
		pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_FILE_MISMATCH\", "
		    "\"data\": { "
		    "\"pkgname\": \"%n\", "
		    "\"pkgversion\": \"%v\", "
		    "\"path\": \"%S\""
		    "}}",
		    ev->e_file_mismatch.pkg,
		    ev->e_file_mismatch.pkg,
		    sbuf_json_escape(buf, ev->e_file_mismatch.file->path));
		break;
	case PKG_EVENT_PLUGIN_ERRNO:
		sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
		    "\"data\": {"
		    "\"plugin\": \"%s\", "
		    "\"msg\": \"%s(%s): %s\","
		    "\"errno\": %d"
		    "}}",
		    pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME),
		    sbuf_json_escape(buf, ev->e_plugin_errno.func),
		    sbuf_json_escape(buf, ev->e_plugin_errno.arg),
		    sbuf_json_escape(buf, strerror(ev->e_plugin_errno.no)),
		    ev->e_plugin_errno.no);
		break;
	case PKG_EVENT_PLUGIN_ERROR:
		sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
		    "\"data\": {"
		    "\"plugin\": \"%s\", "
		    "\"msg\": \"%s\""
		    "}}",
		    pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME),
		    sbuf_json_escape(buf, ev->e_plugin_error.msg));
		break;
	case PKG_EVENT_PLUGIN_INFO:
		sbuf_printf(msg, "{ \"type\": \"INFO_PLUGIN\", "
		    "\"data\": {"
		    "\"plugin\": \"%s\", "
		    "\"msg\": \"%s\""
		    "}}",
		    pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME),
		    sbuf_json_escape(buf, ev->e_plugin_info.msg));
		break;
	case PKG_EVENT_INCREMENTAL_UPDATE:
		sbuf_printf(msg, "{ \"type\": \"INFO_INCREMENTAL_UPDATE\", "
		    "\"data\": {"
		        "\"name\": \"%s\", "
			"\"processed\": %d"
			"}}", ev->e_incremental_update.reponame,
			ev->e_incremental_update.processed);
		break;
	case PKG_EVENT_QUERY_YESNO:
		sbuf_printf(msg, "{ \"type\": \"QUERY_YESNO\", "
		    "\"data\": {"
			"\"msg\": \"%s\","
			"\"default\": \"%d\""
			"}}", ev->e_query_yesno.msg,
			ev->e_query_yesno.deft);
		break;
	case PKG_EVENT_QUERY_SELECT:
		sbuf_printf(msg, "{ \"type\": \"QUERY_SELECT\", "
		    "\"data\": {"
			"\"msg\": \"%s\","
			"\"ncnt\": \"%d\","
			"\"default\": \"%d\","
			"\"items\": ["
			, ev->e_query_select.msg,
			ev->e_query_select.ncnt,
			ev->e_query_select.deft);
		for (i = 0; i < ev->e_query_select.ncnt - 1; i++)
		{
			sbuf_printf(msg, "{ \"text\": \"%s\" },",
				ev->e_query_select.items[i]);
		}
		sbuf_printf(msg, "{ \"text\": \"%s\" } ] }}",
			ev->e_query_select.items[i]);
		break;
	case PKG_EVENT_PROGRESS_START:
		sbuf_printf(msg, "{ \"type\": \"INFO_PROGRESS_START\", "
		  "\"data\": {}}");
		break;
	case PKG_EVENT_PROGRESS_TICK:
		sbuf_printf(msg, "{ \"type\": \"INFO_PROGRESS_TICK\", "
		  "\"data\": { \"current\": %ld, \"total\" : %ld}}",
		  ev->e_progress_tick.current, ev->e_progress_tick.total);
		break;
	case PKG_EVENT_BACKUP:
	case PKG_EVENT_RESTORE:
		break;
	default:
		break;
	}
	sbuf_finish(msg);
	dprintf(eventpipe, "%s\n", sbuf_data(msg));
	sbuf_delete(msg);
	sbuf_delete(buf);
}
Пример #2
0
static void
pipeevent(struct pkg_event *ev)
{
    struct pkg *pkg = NULL;
    struct pkg_dep *dep = NULL;
    struct sbuf *msg, *buf;
    const char *message;
    const char *name, *version, *newversion;

    if (eventpipe < 0)
        return;

    msg = sbuf_new_auto();
    buf = sbuf_new_auto();

    switch(ev->type) {
    case PKG_EVENT_ERRNO:
        sbuf_printf(msg, "{ \"type\": \"ERROR\", "
                    "\"data\": {"
                    "\"msg\": \"%s(%s): %s\","
                    "\"errno\": %d}}",
                    sbuf_json_escape(buf, ev->e_errno.func),
                    sbuf_json_escape(buf, ev->e_errno.arg),
                    sbuf_json_escape(buf, strerror(ev->e_errno.no)),
                    ev->e_errno.no);
        break;
    case PKG_EVENT_ERROR:
        sbuf_printf(msg, "{ \"type\": \"ERROR\", "
                    "\"data\": {\"msg\": \"%s\"}}",
                    sbuf_json_escape(buf, ev->e_pkg_error.msg));
        break;
    case PKG_EVENT_DEVELOPER_MODE:
        sbuf_printf(msg, "{ \"type\": \"ERROR\", "
                    "\"data\": {\"msg\": \"DEVELOPER_MODE: %s\"}}",
                    sbuf_json_escape(buf, ev->e_pkg_error.msg));
        break;
    case PKG_EVENT_FETCHING:
        sbuf_printf(msg, "{ \"type\": \"INFO_FETCH\", "
                    "\"data\": { "
                    "\"url\": \"%s\", "
                    "\"fetched\": %" PRId64 ", "
                    "\"total\": %" PRId64
                    "}}",
                    sbuf_json_escape(buf, ev->e_fetching.url),
                    ev->e_fetching.done,
                    ev->e_fetching.total
                   );
        break;
    case PKG_EVENT_INSTALL_BEGIN:
        pkg_get(ev->e_install_begin.pkg, PKG_NAME, &name,
                PKG_VERSION, &version);

        sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_BEGIN\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\""
                    "}}",
                    name,
                    version
                   );
        break;
    case PKG_EVENT_INSTALL_FINISHED:
        pkg_get(ev->e_install_finished.pkg,
                PKG_MESSAGE, &message,
                PKG_NAME, &name,
                PKG_VERSION, &version);

        sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_FINISHED\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\", "
                    "\"message\": \"%s\""
                    "}}",
                    name,
                    version,
                    sbuf_json_escape(buf, message));
        break;
    case PKG_EVENT_INTEGRITYCHECK_BEGIN:
        sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", "
                    "\"data\": {}}");
        break;
    case PKG_EVENT_INTEGRITYCHECK_FINISHED:
        sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", "
                    "\"data\": {}}");
        break;
    case PKG_EVENT_DEINSTALL_BEGIN:
        pkg_get(ev->e_deinstall_begin.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version);

        sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_BEGIN\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\""
                    "}}",
                    name,
                    version);
        break;
    case PKG_EVENT_DEINSTALL_FINISHED:
        pkg_get(ev->e_deinstall_finished.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version);

        sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_FINISHED\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\""
                    "}}",
                    name,
                    version);
        break;
    case PKG_EVENT_UPGRADE_BEGIN:
        pkg_get(ev->e_upgrade_begin.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version,
                PKG_NEWVERSION, &newversion);

        sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_BEGIN\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\" ,"
                    "\"pkgnewversion\": \"%s\""
                    "}}",
                    name,
                    version,
                    newversion);
        break;
    case PKG_EVENT_UPGRADE_FINISHED:
        pkg_get(ev->e_upgrade_finished.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version,
                PKG_NEWVERSION, &newversion);

        sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_FINISHED\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\" ,"
                    "\"pkgnewversion\": \"%s\""
                    "}}",
                    name,
                    version,
                    newversion);
        break;
    case PKG_EVENT_LOCKED:
        pkg_get(ev->e_locked.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version);
        sbuf_printf(msg, "{ \"type\": \"ERROR_LOCKED\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\""
                    "}}",
                    name,
                    version);
        break;
    case PKG_EVENT_REQUIRED:
        pkg_get(ev->e_required.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version);
        sbuf_printf(msg, "{ \"type\": \"ERROR_REQUIRED\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\", "
                    "\"force\": %s, "
                    "\"required_by\": [",
                    name,
                    version,
                    ev->e_required.force == 1 ? "true": "false");
        while (pkg_rdeps(pkg, &dep) == EPKG_OK)
            sbuf_printf(msg, "{ \"pkgname\": \"%s\", "
                        "\"pkgversion\": \"%s\" }, ",
                        pkg_dep_name(dep),
                        pkg_dep_version(dep));
        sbuf_setpos(msg, sbuf_len(msg) - 2);
        sbuf_cat(msg, "]}}");
        break;
    case PKG_EVENT_ALREADY_INSTALLED:
        pkg_get(ev->e_already_installed.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version);
        sbuf_printf(msg, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\""
                    "}}",
                    name,
                    version);
        break;
    case PKG_EVENT_MISSING_DEP:
        sbuf_printf(msg, "{ \"type\": \"ERROR_MISSING_DEP\", "
                    "\"data\": { "
                    "\"depname\": \"%s\", "
                    "\"depversion\": \"%s\""
                    "}}" ,
                    pkg_dep_name(ev->e_missing_dep.dep),
                    pkg_dep_version(ev->e_missing_dep.dep));
        break;
    case PKG_EVENT_NOREMOTEDB:
        sbuf_printf(msg, "{ \"type\": \"ERROR_NOREMOTEDB\", "
                    "\"data\": { "
                    "\"url\": \"%s\" "
                    "}}" ,
                    ev->e_remotedb.repo);
        break;
    case PKG_EVENT_NOLOCALDB:
        sbuf_printf(msg, "{ \"type\": \"ERROR_NOLOCALDB\", "
                    "\"data\": {} ");
        break;
    case PKG_EVENT_NEWPKGVERSION:
        sbuf_printf(msg, "{ \"type\": \"INFO_NEWPKGVERSION\", "
                    "\"data\": {} ");
        break;
    case PKG_EVENT_FILE_MISMATCH:
        pkg_get(ev->e_file_mismatch.pkg,
                PKG_NAME, &name,
                PKG_VERSION, &version);
        sbuf_printf(msg, "{ \"type\": \"ERROR_FILE_MISMATCH\", "
                    "\"data\": { "
                    "\"pkgname\": \"%s\", "
                    "\"pkgversion\": \"%s\", "
                    "\"path\": \"%s\""
                    "}}",
                    name,
                    version,
                    sbuf_json_escape(buf, pkg_file_path(ev->e_file_mismatch.file)));
        break;
    case PKG_EVENT_PLUGIN_ERRNO:
        sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
                    "\"data\": {"
                    "\"plugin\": \"%s\", "
                    "\"msg\": \"%s(%s): %s\","
                    "\"errno\": %d"
                    "}}",
                    pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME),
                    sbuf_json_escape(buf, ev->e_plugin_errno.func),
                    sbuf_json_escape(buf, ev->e_plugin_errno.arg),
                    sbuf_json_escape(buf, strerror(ev->e_plugin_errno.no)),
                    ev->e_plugin_errno.no);
        break;
    case PKG_EVENT_PLUGIN_ERROR:
        sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", "
                    "\"data\": {"
                    "\"plugin\": \"%s\", "
                    "\"msg\": \"%s\""
                    "}}",
                    pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME),
                    sbuf_json_escape(buf, ev->e_plugin_error.msg));
        break;
    case PKG_EVENT_PLUGIN_INFO:
        sbuf_printf(msg, "{ \"type\": \"INFO_PLUGIN\", "
                    "\"data\": {"
                    "\"plugin\": \"%s\", "
                    "\"msg\": \"%s\""
                    "}}",
                    pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME),
                    sbuf_json_escape(buf, ev->e_plugin_info.msg));
        break;
    default:
        break;
    }
    sbuf_finish(msg);
    dprintf(eventpipe, "%s\n", sbuf_data(msg));
    sbuf_delete(msg);
    sbuf_delete(buf);
}