agama/rust/zypp-agama/zypp-agama-sys/c-layer/include/callbacks.h
2025-11-25 14:08:22 +01:00

326 lines
13 KiB
C

#ifndef C_CALLBACKS_H_
#define C_CALLBACKS_H_
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
struct ProgressData {
// TODO: zypp also reports min/max so it can be either percent, min/max or
// just alive progress. Should we expose all of them? progress value is either
// percent or -1 which means just keep alive progress
long long value;
// pointer to progress name. Owned by zypp, so lives only as long as callback
const char *name;
};
// Progress reporting callback passed to libzypp.
// zypp_data is ProgressData get from zypp
// user_data is never touched by method and is used only to pass local data for
// callback
/// @return true to continue, false to abort. Can be ignored
typedef bool (*ZyppProgressCallback)(struct ProgressData zypp_data,
void *user_data);
void set_zypp_progress_callback(ZyppProgressCallback progress, void *user_data);
// keep in sync with below enum to ensure all entries here is also at the below
// one to allow 1:1 matching.
enum PROBLEM_RESPONSE { PROBLEM_RETRY, PROBLEM_ABORT, PROBLEM_IGNORE };
// NOTE: ensure that order are identical as PROBLEM_RESPONSE and NONE is at the
// end
enum OPTIONAL_PROBLEM_RESPONSE {
OPROBLEM_RETRY,
OPROBLEM_ABORT,
OPROBLEM_IGNORE,
OPROBLEM_NONE
};
enum DownloadProgressError {
DPE_NO_ERROR,
DPE_NOT_FOUND, // the requested Url was not found
DPE_IO, // IO error
DPE_ACCESS_DENIED, // user authent. failed while accessing restricted file
DPE_ERROR // other error
};
typedef void (*ZyppDownloadStartCallback)(const char *url,
const char *localfile,
void *user_data);
typedef bool (*ZyppDownloadProgressCallback)(int value, const char *url,
double bps_avg, double bps_current,
void *user_data);
typedef enum PROBLEM_RESPONSE (*ZyppDownloadProblemCallback)(
const char *url, enum DownloadProgressError error, const char *description,
void *user_data);
typedef void (*ZyppDownloadFinishCallback)(const char *url,
enum DownloadProgressError error,
const char *reason, void *user_data);
// progress for downloading files. There are 4 callbacks:
// 1. start for start of download
// 2. progress to see how it goes
// 3. problem to react when something wrong happen and how to behave
// 4. finish when download finishes
// NOTE: user_data is separated for each call.
struct DownloadProgressCallbacks {
ZyppDownloadStartCallback start;
void *start_data;
ZyppDownloadProgressCallback progress;
void *progress_data;
ZyppDownloadProblemCallback problem;
void *problem_data;
ZyppDownloadFinishCallback finish;
void *finish_data;
};
enum DownloadResolvableError {
DRE_NO_ERROR,
DRE_NOT_FOUND, // the requested Url was not found
DRE_IO, // IO error
DRE_INVALID // the downloaded file is invalid
};
enum DownloadResolvableFileError {
DRFE_NO_ERROR,
DRFE_NOT_FOUND, // the requested Url was not found
DRFE_IO, // IO error
DRFE_ACCESS_DENIED, // user authent. failed while accessing restricted file
DRFE_ERROR // other error
};
// keep in sync with
// https://github.com/openSUSE/libzypp/blob/master/zypp-logic/zypp/target/rpm/RpmDb.h#L376
// maybe there is a better way to export it to C?
enum GPGCheckPackageResult {
CHK_OK = 0, /*!< Signature is OK. */
CHK_NOTFOUND = 1, /*!< Signature is unknown type. */
CHK_FAIL = 2, /*!< Signature does not verify. */
CHK_NOTTRUSTED = 3, /*!< Signature is OK, but key is not trusted. */
CHK_NOKEY = 4, /*!< Public key is unavailable. */
CHK_ERROR = 5, /*!< File does not exist or can't be opened. */
CHK_NOSIG = 6, /*!< File has no gpg signature (only digests). */
};
typedef void (*ZyppDownloadResolvableStartCallback)(void *user_data);
// TODO: do we need more resolvable details? for now just use name and url
typedef enum PROBLEM_RESPONSE (*ZyppDownloadResolvableProblemCallback)(
const char *resolvable_name, enum DownloadResolvableError error,
const char *description, void *user_data);
typedef enum OPTIONAL_PROBLEM_RESPONSE (
*ZyppDownloadResolvableGpgCheckCallback)(
const char *resolvable_name, const char *repo_url,
enum GPGCheckPackageResult check_result, void *user_data);
typedef void (*ZyppDownloadResolvableFileFinishCallback)(
const char *url, const char *local_path,
enum DownloadResolvableFileError error, const char *error_details,
void *user_data);
// progress for downloading resolvables (rpms). There are 3 callbacks now ( can
// be extended with progress and finish one):
// 1. start for start of preload
// 2. problem to react when something wrong happen and how to behave
// 3. gpg_check when there is issue with gpg check on resolvable
// 4. finish_file is when preload finish download of package including failed
// NOTE: user_data is separated for each call.
// NOTE: libzypp provides more data, but only those used by agama is used now.
struct DownloadResolvableCallbacks {
ZyppDownloadResolvableStartCallback start_preload;
void *start_preload_data;
ZyppDownloadResolvableProblemCallback problem;
void *problem_data;
ZyppDownloadResolvableGpgCheckCallback gpg_check;
void *gpg_check_data;
ZyppDownloadResolvableFileFinishCallback file_finish;
void *file_finish_data;
};
/**
* @brief What to do with an unknown GPG key.
* @see zypp::KeyRingReport::KeyTrust in
* https://github.com/openSUSE/libzypp/blob/master/zypp-logic/zypp/KeyRing.h
*/
enum GPGKeyTrust {
/** Reject the key. */
GPGKT_REJECT,
/** Trust key temporary. Will be asked again when something is signed with it.
Even within same session. */
GPGKT_TEMPORARY,
/** Import key and trust it. */
GPGKT_IMPORT
};
/**
* @brief Callback to decide whether to accept an unknown GPG key.
* @param key_id The ID of the GPG key.
* @param key_name The name of the GPG key.
* @param key_fingerprint The fingerprint of the GPG key.
* @param repository_alias The alias of the repository providing the key. Can be
* an empty string if not available.
* @param user_data User-defined data.
* @return A GPGKeyTrust value indicating the action to take.
* @see zypp::KeyRingReport::askUserToAcceptKey in
* https://github.com/openSUSE/libzypp/blob/master/zypp-logic/zypp/KeyRing.h
*/
typedef enum GPGKeyTrust (*GPGAcceptKeyCallback)(const char *key_id,
const char *key_name,
const char *key_fingerprint,
const char *repository_alias,
void *user_data);
/**
* @brief Callback for handling unsigned files.
* @param file The path to the unsigned file.
* @param repository_alias The alias of the repository. Can be an empty string
* if not available.
* @param user_data User-defined data.
* @return true to continue, false to abort.
*/
typedef bool (*GPGUnsignedFile)(const char *file, const char *repository_alias,
void *user_data);
/**
* @brief Callback for handling a file signed by an unknown key.
* @param file The path to the file.
* @param key_id The ID of the unknown GPG key.
* @param repository_alias The alias of the repository. Can be an empty string
* if not available.
* @param user_data User-defined data.
* @return true to continue, false to abort.
*/
typedef bool (*GPGUnknownKey)(const char *file, const char *key_id,
const char *repository_alias, void *user_data);
/**
* @brief Callback for when GPG verification of a signed file fails.
* @param file The path to the file.
* @param key_id The ID of the GPG key.
* @param key_name The name of the GPG key.
* @param key_fingerprint The fingerprint of the GPG key.
* @param repository_alias The alias of the repository. Can be an empty string
* if not available.
* @param user_data User-defined data.
* @return true to continue, false to abort.
*/
typedef bool (*GPGVerificationFailed)(const char *file, const char *key_id,
const char *key_name,
const char *key_fingerprint,
const char *repository_alias,
void *user_data);
/**
* @see zypp::DigestReport in
* https://github.com/openSUSE/libzypp/blob/master/zypp-logic/zypp/Digest.h
*/
typedef bool (*ChecksumMissing)(const char *file, void *user_data);
typedef bool (*ChecksumWrong)(const char *file, const char *expected,
const char *actual, void *user_data);
typedef bool (*ChecksumUnknown)(const char *file, const char *checksum,
void *user_data);
/**
* @brief Callbacks for handling security related issues.
*
* This struct provides callbacks for handling various security-related events
* that can occur during libzypp operations, such as GPG key management and
* checksum verification.
*
* Each callback has a corresponding `_data` pointer that can be used to pass
* user-defined data to the callback function.
*/
struct SecurityCallbacks {
/** @brief Callback to decide whether to accept an unknown GPG key. */
GPGAcceptKeyCallback accept_key;
/** @brief User data for the `accept_key` callback. */
void *accept_key_data;
/** @brief Callback for handling unsigned files. */
GPGUnsignedFile unsigned_file;
/** @brief User data for the `unsigned_file` callback. */
void *unsigned_file_data;
/** @brief Callback for handling files signed with an unknown key. */
GPGUnknownKey unknown_key;
/** @brief User data for the `unknown_key` callback. */
void *unknown_key_data;
/** @brief Callback for handling GPG verification failures. */
GPGVerificationFailed verification_failed;
/** @brief User data for the `verification_failed` callback. */
void *verification_failed_data;
/** @brief Callback for when a checksum is missing. */
ChecksumMissing checksum_missing;
/** @brief User data for the `checksum_missing` callback. */
void *checksum_missing_data;
/** @brief Callback for when a checksum is wrong. */
ChecksumWrong checksum_wrong;
/** @brief User data for the `checksum_wrong` callback. */
void *checksum_wrong_data;
/** @brief Callback for when the checksum type is unknown. */
ChecksumUnknown checksum_unknown;
/** @brief User data for the `checksum_unknown` callback. */
void *checksum_unknown_data;
};
/**
* @brief Errors that can occur during package installation.
* @see zypp::target::rpm::InstallResolvableReport::Error in libzypp.
*/
enum ZyppInstallPackageError {
/** @brief No error occurred. */
PI_NO_ERROR,
/** @brief The requested URL was not found. */
PI_NOT_FOUND,
/** @brief An I/O error occurred. */
PI_IO,
/** @brief The resolvable is invalid. */
PI_INVALID
};
/**
* @brief Callback invoked when the installation of a package starts.
* @param package_name The name of the package being installed.
* @param user_data User-defined data.
*/
typedef void (*ZyppInstallPackageStartCallback)(const char *package_name,
void *user_data);
/**
* @brief Callback for handling problems during package installation.
* @param package_name The name of the package that has a problem.
* @param error The type of error that occurred.
* @param description A description of the problem.
* @param user_data User-defined data.
* @return A PROBLEM_RESPONSE value indicating how to proceed.
*/
typedef enum PROBLEM_RESPONSE (*ZyppInstallPackageProblemCallback)(
const char *package_name, enum ZyppInstallPackageError error,
const char *description, void *user_data);
/**
* @brief Callback invoked when the installation of a package finishes.
* @note We could add a finish message after package install, but YaST does not.
* Should we do it with Agama?
* @param user_data User-defined data.
*/
typedef void (*ZyppInstallPackageFinishCallback)(const char *package_name,
void *user_data);
/**
* @brief Callback for handling problems in package installation scripts (e.g.,
* post-install).
* @param description A description of the script problem.
* @param user_data User-defined data.
* @return A PROBLEM_RESPONSE value indicating how to proceed.
*/
typedef enum PROBLEM_RESPONSE (*ZyppInstallScriptProblemCallback)(
const char *description, void *user_data);
/**
* @brief Callbacks for monitoring the progress of package installation.
*/
struct InstallCallbacks {
ZyppInstallPackageStartCallback package_start;
void *package_start_data;
ZyppInstallPackageProblemCallback package_problem;
void *package_problem_data;
ZyppInstallScriptProblemCallback script_problem;
void *script_problem_data;
ZyppInstallPackageFinishCallback package_finish;
void *package_finish_data;
};
#ifdef __cplusplus
}
#endif
#endif