#include "perl_gpgme.h" static const perl_gpgme_status_code_map_t perl_gpgme_status_code_map[] = { { GPGME_STATUS_EOF, "eof" }, { GPGME_STATUS_ENTER, "enter" }, { GPGME_STATUS_LEAVE, "leave" }, { GPGME_STATUS_ABORT, "abort" }, { GPGME_STATUS_GOODSIG, "goodsig" }, { GPGME_STATUS_BADSIG, "badsig" }, { GPGME_STATUS_ERRSIG, "errsig" }, { GPGME_STATUS_BADARMOR, "badarmor" }, { GPGME_STATUS_RSA_OR_IDEA, "rsa-or-idea" }, { GPGME_STATUS_KEYEXPIRED, "keyexpired" }, { GPGME_STATUS_KEYREVOKED, "keyrevoked" }, { GPGME_STATUS_TRUST_UNDEFINED, "trust-undefined" }, { GPGME_STATUS_TRUST_NEVER, "trust-never" }, { GPGME_STATUS_TRUST_MARGINAL, "trust-marginal" }, { GPGME_STATUS_TRUST_FULLY, "trust-fully" }, { GPGME_STATUS_TRUST_ULTIMATE, "trust-ultimate" }, { GPGME_STATUS_SHM_INFO, "shm-info" }, { GPGME_STATUS_SHM_GET, "shm-get" }, { GPGME_STATUS_SHM_GET_BOOL, "shm-get-bool" }, { GPGME_STATUS_SHM_GET_HIDDEN, "shm-get-hidden" }, { GPGME_STATUS_NEED_PASSPHRASE, "need-passphrase" }, { GPGME_STATUS_VALIDSIG, "validsig" }, { GPGME_STATUS_SIG_ID, "sig-id" }, { GPGME_STATUS_ENC_TO, "enc-to" }, { GPGME_STATUS_NODATA, "nodata" }, { GPGME_STATUS_BAD_PASSPHRASE, "bad-passphrase" }, { GPGME_STATUS_NO_PUBKEY, "no-pubkey" }, { GPGME_STATUS_NO_SECKEY, "no-seckey" }, { GPGME_STATUS_NEED_PASSPHRASE_SYM, "need-passphrase-sym" }, { GPGME_STATUS_DECRYPTION_FAILED, "decryption-failed" }, { GPGME_STATUS_DECRYPTION_OKAY, "decryption-okay" }, { GPGME_STATUS_MISSING_PASSPHRASE, "missing-passphrase" }, { GPGME_STATUS_GOOD_PASSPHRASE, "good-passphrase" }, { GPGME_STATUS_GOODMDC, "goodmdc" }, { GPGME_STATUS_BADMDC, "badmdc" }, { GPGME_STATUS_ERRMDC, "errmdc" }, { GPGME_STATUS_IMPORTED, "imported" }, { GPGME_STATUS_IMPORT_OK, "import-ok" }, { GPGME_STATUS_IMPORT_PROBLEM, "status-import-problem" }, { GPGME_STATUS_IMPORT_RES, "import-res" }, { GPGME_STATUS_FILE_START, "file-start" }, { GPGME_STATUS_FILE_DONE, "file-done" }, { GPGME_STATUS_FILE_ERROR, "file-error" }, { GPGME_STATUS_BEGIN_DECRYPTION, "begin-decryption" }, { GPGME_STATUS_END_DECRYPTION, "end-decryption" }, { GPGME_STATUS_BEGIN_ENCRYPTION, "begin-encryption" }, { GPGME_STATUS_END_ENCRYPTION, "end-encryption" }, { GPGME_STATUS_DELETE_PROBLEM, "delete-problem" }, { GPGME_STATUS_GET_BOOL, "get-bool" }, { GPGME_STATUS_GET_LINE, "get-line" }, { GPGME_STATUS_GET_HIDDEN, "get-hidden" }, { GPGME_STATUS_GOT_IT, "got-it" }, { GPGME_STATUS_PROGRESS, "progress" }, { GPGME_STATUS_SIG_CREATED, "sig-created" }, { GPGME_STATUS_SESSION_KEY, "session-key" }, { GPGME_STATUS_NOTATION_NAME, "notation-name" }, { GPGME_STATUS_NOTATION_DATA, "notation-data" }, { GPGME_STATUS_POLICY_URL, "policy-url" }, { GPGME_STATUS_BEGIN_STREAM, "begin-stream" }, { GPGME_STATUS_END_STREAM, "end-stream" }, { GPGME_STATUS_KEY_CREATED, "key-created" }, { GPGME_STATUS_USERID_HINT, "userid-hint" }, { GPGME_STATUS_UNEXPECTED, "unexpected" }, { GPGME_STATUS_INV_RECP, "inv-recp" }, { GPGME_STATUS_NO_RECP, "no-recp" }, { GPGME_STATUS_ALREADY_SIGNED, "already-signed" }, { GPGME_STATUS_SIGEXPIRED, "sigexpired" }, { GPGME_STATUS_EXPSIG, "expsig" }, { GPGME_STATUS_EXPKEYSIG, "expkeysig" }, { GPGME_STATUS_TRUNCATED, "truncated" }, { GPGME_STATUS_ERROR, "error" }, { GPGME_STATUS_NEWSIG, "newsig" }, { GPGME_STATUS_REVKEYSIG, "revkeysig" }, { GPGME_STATUS_SIG_SUBPACKET, "sig-subpacket" }, { GPGME_STATUS_NEED_PASSPHRASE_PIN, "need-passphrase-pin" }, { GPGME_STATUS_SC_OP_FAILURE, "sc-op-failure" }, { GPGME_STATUS_SC_OP_SUCCESS, "sc-op-success" }, { GPGME_STATUS_CARDCTRL, "cardctrl" }, { GPGME_STATUS_BACKUP_KEY_CREATED, "backup-key-created" }, { GPGME_STATUS_PKA_TRUST_BAD, "pka-trust-bad" }, { GPGME_STATUS_PKA_TRUST_GOOD, "pka-trust-good" }, { GPGME_STATUS_PLAINTEXT, "plaintext" } }; void _perl_gpgme_call_xs (pTHX_ void (*subaddr) (pTHX_ CV *), CV *cv, SV **mark) { dSP; PUSHMARK (mark); (*subaddr) (aTHX_ cv); PUTBACK; } SV * perl_gpgme_new_sv_from_ptr (void *ptr, const char *class) { SV *obj, *sv; HV *stash; obj = (SV *)newHV (); sv_magic (obj, 0, PERL_MAGIC_ext, (const char *)ptr, 0); sv = newRV_noinc (obj); stash = gv_stashpv (class, 0); sv_bless (sv, stash); return sv; } void * perl_gpgme_get_ptr_from_sv (SV *sv, const char *class) { MAGIC *mg; mg = perl_gpgme_get_magic_from_sv (sv, class); return (void *)mg->mg_ptr; } MAGIC * perl_gpgme_get_magic_from_sv (SV *sv, const char *class) { MAGIC *mg; if (!sv || !SvOK (sv) || !SvROK (sv) || (class && !sv_derived_from (sv, class)) || !(mg = mg_find (SvRV (sv), PERL_MAGIC_ext))) { croak ("invalid object"); } return mg; } void perl_gpgme_assert_error (gpgme_error_t err) { if (err == GPG_ERR_NO_ERROR) { return; } croak ("%s: %s", gpgme_strsource (err), gpgme_strerror (err)); } perl_gpgme_callback_t * perl_gpgme_callback_new (SV *func, SV *data, SV *obj, int n_params, perl_gpgme_callback_param_type_t param_types[], int n_retvals, perl_gpgme_callback_retval_type_t retval_types[]) { perl_gpgme_callback_t *cb; Newxz (cb, 1, perl_gpgme_callback_t); cb->func = newSVsv (func); if (data) { cb->data = newSVsv (data); } if (obj) { SvREFCNT_inc (obj); cb->obj = obj; } cb->n_params = n_params; if (cb->n_params) { if (!param_types) { croak ("n_params is %d, but param_types is NULL", n_params); } Newx (cb->param_types, n_params, perl_gpgme_callback_param_type_t); Copy (param_types, cb->param_types, n_params, perl_gpgme_callback_param_type_t); } cb->n_retvals = n_retvals; if (cb->n_retvals) { if (!retval_types) { croak ("n_retvals is %d, but retval_types is NULL", n_retvals); } Newx (cb->retval_types, n_retvals, perl_gpgme_callback_retval_type_t); Copy (retval_types, cb->retval_types, n_retvals, perl_gpgme_callback_retval_type_t); } #ifdef PERL_IMPLICIT_CONTEXT cb->priv = aTHX; #endif return cb; } void perl_gpgme_callback_destroy (perl_gpgme_callback_t *cb) { if (cb) { if (cb->func) { SvREFCNT_dec (cb->func); cb->func = NULL; } if (cb->data) { SvREFCNT_dec (cb->func); cb->func = NULL; } if (cb->obj) { SvREFCNT_dec (cb->obj); cb->obj = NULL; } if (cb->param_types) { Safefree (cb->param_types); cb->n_params = 0; cb->param_types = NULL; } if (cb->retval_types) { Safefree (cb->retval_types); cb->n_retvals = 0; cb->retval_types = NULL; } Safefree (cb); } } void perl_gpgme_callback_invoke (perl_gpgme_callback_t *cb, perl_gpgme_callback_retval_t *retvals, ...) { va_list va_args; int ret, i; I32 call_flags; dPERL_GPGME_CALLBACK_MARSHAL_SP; if (!cb) { croak ("NULL cb in callback_invoke"); } PERL_GPGME_MARSHAL_INIT (cb); ENTER; SAVETMPS; PUSHMARK (sp); EXTEND (sp, cb->n_params + 1); if (cb->obj) { PUSHs (cb->obj); } va_start (va_args, retvals); for (i = 0; i < cb->n_params; i++) { SV *sv; switch (cb->param_types[i]) { case PERL_GPGME_CALLBACK_PARAM_TYPE_STR: sv = newSVpv (va_arg (va_args, char *), 0); break; case PERL_GPGME_CALLBACK_PARAM_TYPE_INT: sv = newSViv (va_arg (va_args, int)); break; case PERL_GPGME_CALLBACK_PARAM_TYPE_CHAR: { char tmp[0]; tmp[0] = va_arg (va_args, int); sv = newSVpv (tmp, 1); break; } case PERL_GPGME_CALLBACK_PARAM_TYPE_STATUS: sv = perl_gpgme_sv_from_status_code (va_arg (va_args, gpgme_status_code_t)); break; default: PUTBACK; croak ("unknown perl_gpgme_callback_param_type_t"); } if (!sv) { PUTBACK; croak ("failed to convert value to sv"); } PUSHs (sv); } va_end (va_args); if (cb->data) { XPUSHs (cb->data); } PUTBACK; if (cb->n_retvals == 0) { call_flags = G_VOID|G_DISCARD; } else if (cb->n_retvals == 1) { call_flags = G_SCALAR; } else { call_flags = G_ARRAY; } ret = call_sv (cb->func, call_flags); SPAGAIN; if (ret != cb->n_retvals) { PUTBACK; croak ("callback didn't return as much values as expected (got: %d, expected: %d)", ret, cb->n_retvals); } for (i = 0; i < ret; i++) { switch (cb->retval_types[i]) { case PERL_GPGME_CALLBACK_RETVAL_TYPE_STR: retvals[i] = (perl_gpgme_callback_retval_t)savepv (POPp); break; default: PUTBACK; croak ("unknown perl_gpgme_callback_retval_type_t"); } } PUTBACK; FREETMPS; LEAVE; } SV * perl_gpgme_protocol_to_string (gpgme_protocol_t protocol) { const char *name = gpgme_get_protocol_name (protocol); if (!name) { return &PL_sv_undef; } return newSVpv (name, 0); } void perl_gpgme_hv_store (HV *hv, const char *key, I32 key_len, SV *val) { SV **ret; if (key_len == 0) { key_len = strlen (key); } ret = hv_store (hv, key, key_len, val, 0); if (!ret) { croak ("failed to store value inside hash"); } } SV * perl_gpgme_hashref_from_engine_info (gpgme_engine_info_t info) { SV *sv; HV *hv; hv = newHV (); if (info->file_name) { perl_gpgme_hv_store (hv, "file_name", 9, newSVpv (info->file_name, 0)); } if (info->home_dir) { perl_gpgme_hv_store (hv, "home_dir", 8, newSVpv (info->home_dir, 0)); } if (info->version) { perl_gpgme_hv_store (hv, "version", 7, newSVpv (info->version, 0)); } if (info->req_version) { perl_gpgme_hv_store (hv, "req_version", 11, newSVpv (info->req_version, 0)); } perl_gpgme_hv_store (hv, "protocol", 8, perl_gpgme_protocol_to_string (info->protocol)); sv = newRV_noinc ((SV *)hv); return sv; } SV * perl_gpgme_pubkey_algo_to_string (gpgme_pubkey_algo_t algo) { const char *name = gpgme_pubkey_algo_name (algo); if (!name) { return &PL_sv_undef; } return newSVpv (name, 0); } SV * perl_gpgme_hashref_from_subkey (gpgme_subkey_t subkey) { SV *sv; HV *hv; hv = newHV (); perl_gpgme_hv_store (hv, "revoked", 7, newSVuv (subkey->revoked)); perl_gpgme_hv_store (hv, "expired", 7, newSVuv (subkey->expired)); perl_gpgme_hv_store (hv, "disabled", 8, newSVuv (subkey->disabled)); perl_gpgme_hv_store (hv, "invalid", 7, newSVuv (subkey->invalid)); perl_gpgme_hv_store (hv, "can_encrypt", 11, newSVuv (subkey->can_encrypt)); perl_gpgme_hv_store (hv, "can_sign", 8, newSVuv (subkey->can_sign)); perl_gpgme_hv_store (hv, "can_certify", 11, newSVuv (subkey->can_certify)); perl_gpgme_hv_store (hv, "secret", 6, newSVuv (subkey->secret)); perl_gpgme_hv_store (hv, "can_authenticate", 16, newSVuv (subkey->can_authenticate)); perl_gpgme_hv_store (hv, "is_qualified", 12, newSVuv (subkey->is_qualified)); perl_gpgme_hv_store (hv, "pubkey_algo", 11, perl_gpgme_pubkey_algo_to_string (subkey->pubkey_algo)); perl_gpgme_hv_store (hv, "length", 6, newSVuv (subkey->length)); if (subkey->keyid) { perl_gpgme_hv_store (hv, "keyid", 5, newSVpv (subkey->keyid, 0)); } if (subkey->fpr) { perl_gpgme_hv_store (hv, "fpr", 3, newSVpv (subkey->fpr, 0)); } perl_gpgme_hv_store (hv, "timestamp", 9, newSViv (subkey->timestamp)); /* FIXME: long int vs. int? */ perl_gpgme_hv_store (hv, "expires", 7, newSViv (subkey->expires)); /* ditto */ sv = newRV_noinc ((SV *)hv); return sv; } SV * perl_gpgme_hashref_from_uid (gpgme_user_id_t uid) { SV *sv; HV *hv; hv = newHV (); perl_gpgme_hv_store (hv, "revoked", 7, newSVuv (uid->revoked)); perl_gpgme_hv_store (hv, "invalid", 7, newSVuv (uid->invalid)); perl_gpgme_hv_store (hv, "validity", 8, perl_gpgme_validity_to_string (uid->validity)); if (uid->uid) { perl_gpgme_hv_store (hv, "uid", 3, newSVpv (uid->uid, 0)); } if (uid->name) { perl_gpgme_hv_store (hv, "name", 4, newSVpv (uid->name, 0)); } if (uid->email) { perl_gpgme_hv_store (hv, "email", 5, newSVpv (uid->email, 0)); } if (uid->comment) { perl_gpgme_hv_store (hv, "comment", 7, newSVpv (uid->comment, 0)); } if (uid->signatures) { perl_gpgme_hv_store (hv, "signatures", 10, perl_gpgme_array_ref_from_signatures (uid->signatures)); } sv = newRV_noinc ((SV *)hv); return sv; } SV * perl_gpgme_array_ref_from_signatures (gpgme_key_sig_t sig) { SV *sv; AV *av; gpgme_key_sig_t i; av = newAV (); for (i = sig; i != NULL; i = i->next) { av_push (av, perl_gpgme_hashref_from_signature (i)); } sv = newRV_noinc ((SV *)av); return sv; } SV * perl_gpgme_hashref_from_signature (gpgme_key_sig_t sig) { SV *sv; HV *hv; hv = newHV (); perl_gpgme_hv_store (hv, "revoked", 7, newSVuv (sig->revoked)); perl_gpgme_hv_store (hv, "expired", 7, newSVuv (sig->expired)); perl_gpgme_hv_store (hv, "invalid", 7, newSVuv (sig->invalid)); perl_gpgme_hv_store (hv, "exportable", 10, newSVuv (sig->exportable)); perl_gpgme_hv_store (hv, "pubkey_algo", 11, perl_gpgme_pubkey_algo_to_string (sig->pubkey_algo)); if (sig->keyid) { perl_gpgme_hv_store (hv, "keyid", 5, newSVpv (sig->keyid, 0)); } perl_gpgme_hv_store (hv, "timestamp", 9, newSViv (sig->timestamp)); /* FIXME: long int vs. IV? */ perl_gpgme_hv_store (hv, "expires", 7, newSViv (sig->expires)); /* ditto */ if (sig->status != GPG_ERR_NO_ERROR) { perl_gpgme_hv_store (hv, "status", 6, newSVpvf ("%s: %s", gpgme_strsource (sig->status), gpgme_strerror (sig->status))); } if (sig->uid) { perl_gpgme_hv_store (hv, "uid", 3, newSVpv (sig->uid, 0)); } if (sig->name) { perl_gpgme_hv_store (hv, "name", 4, newSVpv (sig->name, 0)); } if (sig->email) { perl_gpgme_hv_store (hv, "email", 5, newSVpv (sig->email, 0)); } if (sig->comment) { perl_gpgme_hv_store (hv, "comment", 7, newSVpv (sig->comment, 0)); } /* FIXME: really export this? */ perl_gpgme_hv_store (hv, "sig_class", 9, newSVuv (sig->sig_class)); if (sig->notations) { perl_gpgme_hv_store (hv, "notations", 9, perl_gpgme_array_ref_from_notations (sig->notations)); } sv = newRV_noinc ((SV *)hv); return sv; } SV * perl_gpgme_array_ref_from_notations (gpgme_sig_notation_t notations) { SV *sv; AV *av; gpgme_sig_notation_t i; av = newAV (); for (i = notations; i != NULL; i = i->next) { av_push (av, perl_gpgme_hashref_from_notation (i)); } sv = newRV_noinc ((SV *)av); return sv; } SV * perl_gpgme_hashref_from_notation (gpgme_sig_notation_t notation) { SV *sv; HV *hv; hv = newHV (); if (notation->name) { perl_gpgme_hv_store (hv, "name", 4, newSVpv (notation->name, notation->name_len)); } if (notation->value) { perl_gpgme_hv_store (hv, "value", 5, newSVpv (notation->value, notation->value_len)); } perl_gpgme_hv_store (hv, "flags", 5, perl_gpgme_avref_from_notation_flags (notation->flags)); perl_gpgme_hv_store (hv, "human_readable", 14, newSVuv (notation->human_readable)); perl_gpgme_hv_store (hv, "critical", 8, newSVuv (notation->critical)); sv = newRV_noinc ((SV *)hv); return sv; } SV * perl_gpgme_avref_from_notation_flags (gpgme_sig_notation_flags_t flags) { SV *sv; AV *av; av = newAV (); if (flags & GPGME_SIG_NOTATION_HUMAN_READABLE) { av_push (av, newSVpv ("human-readable", 0)); } if (flags & GPGME_SIG_NOTATION_CRITICAL) { av_push (av, newSVpv ("critical", 0)); } sv = newRV_inc ((SV *)av); return sv; } SV * perl_gpgme_validity_to_string (gpgme_validity_t validity) { SV *ret; switch (validity) { case GPGME_VALIDITY_UNKNOWN: ret = newSVpvn ("unknown", 7); break; case GPGME_VALIDITY_UNDEFINED: ret = newSVpvn ("undefined", 9); break; case GPGME_VALIDITY_NEVER: ret = newSVpvn ("never", 5); break; case GPGME_VALIDITY_MARGINAL: ret = newSVpvn ("marginal", 8); break; case GPGME_VALIDITY_FULL: ret = newSVpvn ("full", 4); break; case GPGME_VALIDITY_ULTIMATE: ret = newSVpvn ("ultimate", 8); break; default: ret = &PL_sv_undef; } return ret; } SV * perl_gpgme_hashref_from_verify_result (gpgme_verify_result_t result) { SV *sv; HV *hv; hv = newHV (); if (result->file_name) { perl_gpgme_hv_store (hv, "file_name", 9, newSVpv (result->file_name, 0)); } if (result->signatures) { perl_gpgme_hv_store (hv, "signatures", 10, perl_gpgme_array_ref_from_verify_signatures (result->signatures)); } sv = newRV_noinc ((SV *)hv); return sv; } SV * perl_gpgme_array_ref_from_verify_signatures (gpgme_signature_t sig) { SV *sv; AV *av; gpgme_signature_t i; av = newAV (); for (i = sig; i != NULL; i = i->next) { av_push (av, perl_gpgme_hashref_from_verify_signature (i)); } sv = newRV_noinc ((SV *)av); return sv; } SV * perl_gpgme_hashref_from_verify_signature (gpgme_signature_t sig) { SV *sv; HV *hv; hv = newHV (); perl_gpgme_hv_store (hv, "summary", 7, perl_gpgme_sigsum_to_string (sig->summary)); if (sig->fpr) { perl_gpgme_hv_store (hv, "fpr", 3, newSVpv (sig->fpr, 0)); } if (sig->status != GPG_ERR_NO_ERROR) { perl_gpgme_hv_store (hv, "status", 6, newSVpvf ("%s: %s", gpgme_strsource (sig->status), gpgme_strerror (sig->status))); } perl_gpgme_hv_store (hv, "notations", 9, perl_gpgme_array_ref_from_notations (sig->notations)); perl_gpgme_hv_store (hv, "timestamp", 9, newSVuv (sig->timestamp)); /* FIXME: long uint vs. UV */ perl_gpgme_hv_store (hv, "exp_timestamp", 13, newSVuv (sig->exp_timestamp)); /* ditto */ perl_gpgme_hv_store (hv, "wrong_key_usage", 15, newSVuv (sig->wrong_key_usage)); perl_gpgme_hv_store (hv, "pka_trust", 9, newSVuv (sig->pka_trust)); perl_gpgme_hv_store (hv, "validity", 8, perl_gpgme_validity_to_string (sig->validity)); if (sig->validity_reason != GPG_ERR_NO_ERROR) { perl_gpgme_hv_store (hv, "validity_reason", 15, newSVpvf ("%s: %s", gpgme_strsource (sig->status), gpgme_strerror (sig->status))); } perl_gpgme_hv_store (hv, "pubkey_algo", 11, perl_gpgme_pubkey_algo_to_string (sig->pubkey_algo)); perl_gpgme_hv_store (hv, "hash_algo", 9, perl_gpgme_hash_algo_to_string (sig->hash_algo)); if (sig->pka_address) { perl_gpgme_hv_store (hv, "pka_address", 11, newSVpv (sig->pka_address, 0)); } sv = newRV_noinc ((SV *)hv); return sv; } SV * perl_gpgme_sigsum_to_string (gpgme_sigsum_t summary) { SV *sv; AV *av; av = newAV (); if (summary & GPGME_SIGSUM_VALID) { av_push (av, newSVpv ("valid", 0)); } if (summary & GPGME_SIGSUM_GREEN) { av_push (av, newSVpv ("green", 0)); } if (summary & GPGME_SIGSUM_RED) { av_push (av, newSVpv ("red", 0)); } if (summary & GPGME_SIGSUM_KEY_REVOKED) { av_push (av, newSVpv ("key-revoked", 0)); } if (summary & GPGME_SIGSUM_KEY_EXPIRED) { av_push (av, newSVpv ("key-expired", 0)); } if (summary & GPGME_SIGSUM_SIG_EXPIRED) { av_push (av, newSVpv ("sig-expired", 0)); } if (summary & GPGME_SIGSUM_CRL_MISSING) { av_push (av, newSVpv ("crl-missing", 0)); } if (summary & GPGME_SIGSUM_CRL_TOO_OLD) { av_push (av, newSVpv ("crl-too-old", 0)); } if (summary & GPGME_SIGSUM_BAD_POLICY) { av_push (av, newSVpv ("bad-policy", 0)); } if (summary & GPGME_SIGSUM_SYS_ERROR) { av_push (av, newSVpv ("sys-error", 0)); } sv = newRV_noinc ((SV *)av); return sv; } SV * perl_gpgme_hash_algo_to_string (gpgme_hash_algo_t algo) { const char *name = gpgme_hash_algo_name (algo); if (!name) { return &PL_sv_undef; } return newSVpv (name, 0); } SV * perl_gpgme_hashref_from_trust_item (gpgme_trust_item_t item) { SV *sv; HV *hv; hv = newHV (); if (item->keyid) { perl_gpgme_hv_store (hv, "keyid", 5, newSVpv (item->keyid, 0)); } perl_gpgme_hv_store (hv, "type", 4, newSVpv (item->type == 1 ? "key" : "uid", 0)); perl_gpgme_hv_store (hv, "level", 5, newSViv (item->level)); if (item->type == 1 && item->owner_trust) { perl_gpgme_hv_store (hv, "owner_trust", 11, newSVpv (item->owner_trust, 0)); } if (item->validity) { perl_gpgme_hv_store (hv, "validity", 8, newSVpv (item->validity, 0)); } if (item->type == 2 && item->name) { perl_gpgme_hv_store (hv, "name", 4, newSVpv (item->name, 0)); } sv = newRV_noinc ((SV *)hv); return sv; } SV * perl_gpgme_sv_from_status_code (gpgme_status_code_t status) { int i; SV *ret = NULL; for (i = 0; i < sizeof (perl_gpgme_status_code_map) / sizeof (perl_gpgme_status_code_map[0]); i++) { perl_gpgme_status_code_map_t map = perl_gpgme_status_code_map[i]; if (map.status == status) { ret = newSVpv (map.string, 0); break; } } if (!ret) { croak ("unknown status code"); } return ret; } SV * perl_gpgme_genkey_result_to_sv (gpgme_genkey_result_t result) { SV *sv; HV *hv; hv = newHV (); perl_gpgme_hv_store (hv, "primary", 7, newSViv (result->primary)); perl_gpgme_hv_store (hv, "sub", 3, newSViv (result->sub)); if (result->fpr) { perl_gpgme_hv_store (hv, "fpr", 3, newSVpv (result->fpr, 0)); } sv = newRV_noinc ((SV *)hv); return sv; }