#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;
}