X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-perl/blobdiff_plain/a1a90aaf554eb974e39e34b513747eb666180776..8c0425124f855635cc5c7bbbffbfe94b6c4bd161:/key.xs diff --git a/key.xs b/key.xs index d4162e9..db58921 100644 --- a/key.xs +++ b/key.xs @@ -27,6 +27,14 @@ MODULE = Catacomb PACKAGE = Catacomb::Key PREFIX = key_ +SV * +DESTROY(k) + Key *k + CODE: + keyfile_dec(k->kf); + DESTROY(k); + XSRETURN_YES; + bool key_chkident(me, p) SV *me @@ -61,7 +69,17 @@ Key_Data * data(k) Key *k CODE: - RETVAL = &k->k->k; + RETVAL = k->k->k; + key_incref(RETVAL); + OUTPUT: + RETVAL + +KeyErr +setdata(k, kd) + Key *k + Key_Data *kd + CODE: + RETVAL = key_setkeydata(&k->kf->kf, k->k, kd); OUTPUT: RETVAL @@ -102,20 +120,20 @@ key_setcomment(k, p) Key *k char *p C_ARGS: - k->kf, k->k, p + &k->kf->kf, k->k, p KeyErr key_settag(k, p) Key *k char *p C_ARGS: - k->kf, k->k, p + &k->kf->kf, k->k, p KeyErr key_delete(k) Key *k C_ARGS: - k->kf, k->k + &k->kf->kf, k->k SV * fulltag(k) @@ -124,7 +142,7 @@ fulltag(k) dstr d = DSTR_INIT; CODE: key_fulltag(k->k, &d); - RETVAL = newSVpv(d.buf, d.len); + RETVAL = newSVpvn(d.buf, d.len); dstr_destroy(&d); OUTPUT: RETVAL @@ -134,25 +152,35 @@ key_getattr(k, a) Key *k char *a C_ARGS: - k->kf, k->k, a + &k->kf->kf, k->k, a KeyErr -key_putattr(k, a, v) +putattr(k, a, v = &PL_sv_undef) Key *k char *a - char *v - C_ARGS: - k->kf, k->k, a, v + SV *v + PREINIT: + char *vv; + STRLEN len; + CODE: + if (!SvOK(v)) + vv = 0; + else + vv = SvPV(v, len); + RETVAL = key_putattr(&k->kf->kf, k->k, a, vv); + OUTPUT: + RETVAL -void -attrlist(k) +Key_AttrIter * +attriter(k) Key *k - PREINIT: - key_attriter i; - const char *a, *v; - PPCODE: - for (key_mkattriter(&i, k->k); key_nextattr(&i, &a, &v); ) - XPUSHs(sv_2mortal(newSVpv((char *)a, strlen(a)))); + CODE: + RETVAL = CREATE(Key_AttrIter); + key_mkattriter(&RETVAL->i, k->k); + RETVAL->kf = k->kf; + k->kf->ref++; + OUTPUT: + RETVAL bool expiredp(k) @@ -166,31 +194,22 @@ KeyErr key_expire(k) Key *k C_ARGS: - k->kf, k->k + &k->kf->kf, k->k KeyErr key_used(k, t) Key *k time_t t C_ARGS: - k->kf, k->k, t + &k->kf->kf, k->k, t bool -fingerprint(k, h, kfiltstr) +key_fingerprint(k, h, kf = 0) Key *k ghash *h - char *kfiltstr - PREINIT: - key_filter kfilt; - dstr d = DSTR_INIT; - CODE: - if (!kfiltstr) - kfilt.f = kfilt.m = 0; - else if (key_readflags(kfiltstr, 0, &kfilt.f, &kfilt.m)) - croak("bad filter string `%s'", kfiltstr); - RETVAL = key_fingerprint(k->k, h, &kfilt); - OUTPUT: - RETVAL + Key_Filter *kf + C_ARGS: + k->k, h, kf const char * key_strerror(me, err) @@ -199,72 +218,101 @@ key_strerror(me, err) C_ARGS: err -MODULE = Catacomb PACKAGE = Catacomb::Key::Data PREFIX = key_ +MODULE = Catacomb PACKAGE = Catacomb::Key::AttrIter -Key_Data * -_new(me) - SV *me - CODE: - RETVAL = CREATE(key_data); - RETVAL->e = 0; - RETVAL->u.k.k = 0; - RETVAL->u.k.sz = 0; - OUTPUT: - RETVAL +void +next(i) + Key_AttrIter *i + PREINIT: + const char *a, *v; + PPCODE: + if (key_nextattr(&i->i, &a, &v)) { + XPUSHs(sv_2mortal(newSVpv(a, 0))); + if (GIMME_V == G_ARRAY) + XPUSHs(sv_2mortal(newSVpv(v, 0))); + } SV * -destroy(kd) - Key_Data *kd +DESTROY(i) + Key_AttrIter *i CODE: - key_destroy(kd); + keyfile_dec(i->kf); + DESTROY(i); XSRETURN_YES; -SV * -setbinary(kd, sv) - Key_Data *kd - SV *sv +MODULE = Catacomb PACKAGE = Catacomb::Key::Filter + +Key_Filter * +new(me, f = 0, m = 0) + SV *me + SV *f + SV *m PREINIT: char *p; STRLEN len; CODE: - p = SvPV(sv, len); - key_binary(kd, p, len); - XSRETURN_YES; + RETVAL = CREATE(Key_Filter); + if (!f || !SvOK(f)) + RETVAL->f = RETVAL->m = 0; + else if (m) { + RETVAL->f = SvUV(f); + RETVAL->m = SvUV(m); + } else { + p = SvPV(f, len); + if (key_readflags(p, 0, &RETVAL->f, &RETVAL->m)) { + DESTROY(RETVAL); + RETVAL = 0; + } + } + OUTPUT: + RETVAL SV * -setencrypted(kd, sv) - Key_Data *kd - SV *sv - PREINIT: - char *p; - STRLEN len; +DESTROY(kf) + Key_Filter *kf CODE: - p = SvPV(sv, len); - key_encrypted(kd, p, len); + if (!kf) + XSRETURN_UNDEF; + DESTROY(kf); XSRETURN_YES; SV * -setmp(kd, x) - Key_Data *kd - mp *x +tostring(kf) + Key_Filter *kf + PREINIT: + dstr d = DSTR_INIT; CODE: - key_mp(kd, x); - XSRETURN_YES; + if (!kf) + XSRETURN_UNDEF; + key_writeflags(kf->f, &d); + RETVAL = newSVpvn(d.buf, d.len); + dstr_destroy(&d); + OUTPUT: + RETVAL -SV * -setstring(kd, p) - Key_Data *kd - char *p +UV +f(kf) + Key_Filter *kf CODE: - key_string(kd, p); - XSRETURN_YES; + RETVAL = kf ? kf->f : 0; + OUTPUT: + RETVAL + +UV +m(kf) + Key_Filter *kf + CODE: + RETVAL = kf ? kf->m : 0; + OUTPUT: + RETVAL + +MODULE = Catacomb PACKAGE = Catacomb::Key::Data PREFIX = key_ SV * -setec(kd, p) +DESTROY(kd) Key_Data *kd - EC_Point *p CODE: - key_ec(kd, p); + key_drop(kd); XSRETURN_YES; U32 @@ -275,251 +323,362 @@ flags(kd) OUTPUT: RETVAL +void +readflags(me, p) + SV *me + char *p + PREINIT: + unsigned f, m; + PPCODE: + if (key_readflags(p, &p, &f, &m) || *p) + croak("bad flags string"); + XPUSHs(sv_2mortal(newSVuv(m))); + XPUSHs(sv_2mortal(newSVuv(f))); + SV * -getbinary(kd) - Key_Data *kd +getflags(me, f) + SV *me + U32 f + PREINIT: + dstr d = DSTR_INIT; CODE: - if ((kd->e & KF_ENCMASK) != KENC_BINARY) - croak("key is not binary"); - RETVAL = newSVpv(kd->u.k.k, kd->u.k.sz); + key_writeflags(f, &d); + RETVAL = newSVpvn(d.buf, d.len); + dstr_destroy(&d); OUTPUT: RETVAL SV * -getencrypted(kd) +setflags(kd, f) Key_Data *kd + U32 f CODE: - if ((kd->e & KF_ENCMASK) != KENC_ENCRYPT) - croak("key is not encrypted"); - RETVAL = newSVpv(kd->u.k.k, kd->u.k.sz); - OUTPUT: - RETVAL + kd->e = (kd->e & KF_ENCMASK) | (f & ~KF_ENCMASK); + XSRETURN_YES; -mp * -getmp(kd) +void +read(me, p) + SV *me + char *p + PREINIT: + key_data *kd; + char *pp; + PPCODE: + if ((kd = key_read(p, &pp)) != 0) { + XPUSHs(RET(kd, keydata_type(kd))); + if (GIMME_V == G_ARRAY) + XPUSHs(sv_2mortal(newSVpvn(pp, strlen(pp)))); + } + +SV * +write(kd, kf = 0) Key_Data *kd + Key_Filter *kf + PREINIT: + dstr d = DSTR_INIT; CODE: - if ((kd->e & KF_ENCMASK) != KENC_MP) - croak("key is not bignum"); - RETVAL = kd->u.m; + if (key_write(kd, &d, kf)) + RETVAL = newSVpvn(d.buf, d.len); + else + RETVAL = &PL_sv_undef; + dstr_destroy(&d); OUTPUT: RETVAL -EC_Point * -getec(kd) - Key_Data *kd +Key_Data * +decode(me, sv) + SV *me + SV *sv + PREINIT: + char *p; + STRLEN len; CODE: - if ((kd->e & KF_ENCMASK) != KENC_EC) - croak("key is not a curve point"); - RETVAL = CREATE(ec); - EC_CREATE(RETVAL); - EC_COPY(RETVAL, &kd->u.e); + p = SvPV(sv, len); + RETVAL = key_decode(p, len); OUTPUT: RETVAL -char * -getstring(kd) +SV * +encode(kd, kf = 0) Key_Data *kd + Key_Filter *kf + PREINIT: + dstr d = DSTR_INIT; CODE: - if ((kd->e & KF_ENCMASK) != KENC_STRING) - croak("key is not string"); - RETVAL = kd->u.p; + if (key_encode(kd, &d, kf)) + RETVAL = newSVpvn(d.buf, d.len); + else + RETVAL = &PL_sv_undef; + dstr_destroy(&d); OUTPUT: RETVAL -SV * -setstruct(kd) +Key_Data * +lock(kd, key) Key_Data *kd + SV *key + PREINIT: + STRLEN len; + char *p; CODE: - key_structure(kd); - XSRETURN_YES; + p = SvPV(key, len); + key_lock(&RETVAL, kd, p, len); + OUTPUT: + RETVAL Key_Data * -key_structfind(kd, tag) +plock(kd, tag) Key_Data *kd char *tag + PREINIT: + int rc; + CODE: + if ((rc = key_plock(&RETVAL, kd, tag)) != 0) { + keyerr(rc); + RETVAL = 0; + } + OUTPUT: + RETVAL -Key_Data * -key_structcreate(kd, tag) +bool +key_match(kd, kf) Key_Data *kd - char *tag + Key_Filter *kf -void -getstruct(kd) - Key_Data *kd +MODULE = Catacomb PACKAGE = Catacomb::Key::Data::Binary PREFIX = key_ + +Key_Data * +new(me, sv, f = 0) + SV *me + SV *sv + unsigned f PREINIT: - sym_iter i; - key_struct *ks; - PPCODE: - if ((kd->e & KF_ENCMASK) != KENC_STRUCT) - croak("key is not structured"); - for (sym_mkiter(&i, &kd->u.s); ks = sym_next(&i); ) - XPUSHs(RET(&ks->k, "Catacomb::Key::Data")); + char *p; + STRLEN len; + CODE: + p = SvPV(sv, len); + RETVAL = key_newbinary(f, p, len); + OUTPUT: + RETVAL SV * -structdel(kd, tag) +bin(kd) Key_Data *kd - char *tag - PREINIT: - key_struct *ks; CODE: - if ((kd->e & KF_ENCMASK) != KENC_STRUCT) - croak("key is not structured"); - if ((ks = sym_find(&kd->u.s, tag, -1, 0, 0)) == 0) - XSRETURN_UNDEF; - sym_remove(&kd->u.s, ks); - XSRETURN_YES; + RETVAL = newSVpvn((char *)kd->u.k.k, kd->u.k.sz); + OUTPUT: + RETVAL -void -readflags(me, p) +MODULE = Catacomb PACKAGE = Catacomb::Key::Data::Encrypted PREFIX = key_ + +Key_Data * +new(me, sv, f = 0) SV *me - char *p + SV *sv + unsigned f PREINIT: - unsigned f, m; - PPCODE: - if (key_readflags(p, &p, &f, &m) || *p) - croak("bad flags string"); - XPUSHs(sv_2mortal(newSVuv(m))); - XPUSHs(sv_2mortal(newSVuv(f))); + char *p; + STRLEN len; + CODE: + p = SvPV(sv, len); + RETVAL = key_newencrypted(f, p, len); + OUTPUT: + RETVAL SV * -getflags(me, f) - SV *me - U32 f - PREINIT: - dstr d = DSTR_INIT; +ct(kd) + Key_Data *kd CODE: - key_writeflags(f, &d); - RETVAL = newSVpv(d.buf, d.len); - dstr_destroy(&d); + RETVAL = newSVpvn((char *)kd->u.k.k, kd->u.k.sz); OUTPUT: RETVAL +SV * +lock(kd, key) + Key_Data *kd + SV *key + CODE: + croak("already encrypted"); + +SV * +plock(kd, tag) + Key_Data *kd + char *tag + CODE: + croak("already encrypted"); + Key_Data * -copy(kd, kfiltstr = 0) +unlock(kd, key) Key_Data *kd - char *kfiltstr + SV *key PREINIT: - key_filter kfilt; - CODE: - if (!kfiltstr) - kfilt.f = kfilt.m = 0; - else if (key_readflags(kfiltstr, 0, &kfilt.f, &kfilt.m)) - croak("bad filter string `%s'", kfiltstr); - RETVAL = CREATE(key_data); - if (!key_copy(RETVAL, kd, &kfilt)) { - DESTROY(RETVAL); + STRLEN len; + char *p; + int rc; + CODE: + p = SvPV(key, len); + if ((rc = key_unlock(&RETVAL, kd, p, len)) != 0) { + keyerr(rc); RETVAL = 0; } OUTPUT: RETVAL Key_Data * -plock(kd, tag) +punlock(kd, tag) Key_Data *kd char *tag + PREINIT: + int rc; CODE: - RETVAL = CREATE(Key_Data); - if (key_plock(tag, kd, RETVAL)) { - DESTROY(RETVAL); + if ((rc = key_punlock(&RETVAL, kd, tag)) != 0) { + keyerr(rc); RETVAL = 0; } OUTPUT: RETVAL +MODULE = Catacomb PACKAGE = Catacomb::Key::Data::MP PREFIX = key_ + Key_Data * -punlock(kd, tag) +new(me, x, f = 0) + SV *me + mp *x + unsigned f + CODE: + RETVAL = key_newmp(f, x); + OUTPUT: + RETVAL + +mp * +mp(kd) Key_Data *kd - char *tag CODE: - RETVAL = CREATE(Key_Data); - if (key_punlock(tag, kd, RETVAL)) { - DESTROY(RETVAL); - RETVAL = 0; - } + RETVAL = MP_COPY(kd->u.m); OUTPUT: RETVAL +MODULE = Catacomb PACKAGE = Catacomb::Key::Data::EC PREFIX = key_ + Key_Data * -read(me, p) +new(me, p, f = 0) SV *me - char *p + ec *p + unsigned f CODE: - RETVAL = CREATE(key_data); - if (key_read(p, RETVAL, 0)) { - DESTROY(RETVAL); - RETVAL = 0; - } + RETVAL = key_newec(f, p); OUTPUT: RETVAL -SV * -write(kd, kfiltstr = 0) +ec * +ec(kd) Key_Data *kd - char *kfiltstr - PREINIT: - key_filter kfilt; - dstr d = DSTR_INIT; CODE: - if (!kfiltstr) - kfilt.f = kfilt.m = 0; - else if (key_readflags(kfiltstr, 0, &kfilt.f, &kfilt.m)) - croak("bad filter string `%s'", kfiltstr); - if (key_write(kd, &d, &kfilt)) - RETVAL = newSVpv(d.buf, d.len); - else - RETVAL = &PL_sv_undef; - dstr_destroy(&d); + RETVAL = CREATE(ec); + EC_CREATE(RETVAL); + EC_COPY(RETVAL, &kd->u.e); OUTPUT: RETVAL +MODULE = Catacomb PACKAGE = Catacomb::Key::Data::String PREFIX = key_ + Key_Data * -decode(me, sv) +new(me, p, f = 0) SV *me - SV *sv - PREINIT: - char *p; - STRLEN len; + char *p + unsigned f CODE: - p = SvPV(sv, len); - RETVAL = CREATE(key_data); - if (key_decode(p, len, RETVAL)) { - DESTROY(RETVAL); - RETVAL = 0; - } + RETVAL = key_newstring(f, p); + OUTPUT: + RETVAL + +char * +str(kd) + Key_Data *kd + CODE: + RETVAL = kd->u.p; + OUTPUT: + RETVAL + +MODULE = Catacomb PACKAGE = Catacomb::Key::Data::Structured PREFIX = key_ + +Key_Data * +new() + CODE: + RETVAL = key_newstruct(); + OUTPUT: + RETVAL + +Key_StructIter * +iterate(kd) + Key_Data *kd + CODE: + RETVAL = CREATE(Key_StructIter); + sym_mkiter(RETVAL, &kd->u.s); + OUTPUT: + RETVAL + +Key_Data * +find(kd, tag) + Key_Data *kd + char *tag + CODE: + RETVAL = key_structfind(kd, tag); + if (RETVAL) key_incref(RETVAL); OUTPUT: RETVAL SV * -encode(kd, kfiltstr = 0) +del(kd, tag) Key_Data *kd - char *kfiltstr + char *tag + CODE: + key_structset(kd, tag, 0); + XSRETURN_YES; + +SV * +set(kd, tag, kdnew = 0) + Key_Data *kd + char *tag + Key_Data *kdnew + CODE: + key_structset(kd, tag, kdnew); + XSRETURN_YES; + +MODULE = Catacomb PACKAGE = Catacomb::Key::StructIter + +SV * +next(i) + Key_StructIter *i PREINIT: - key_filter kfilt; - dstr d = DSTR_INIT; + key_struct *s; CODE: - if (!kfiltstr) - kfilt.f = kfilt.m = 0; - else if (key_readflags(kfiltstr, 0, &kfilt.f, &kfilt.m)) - croak("bad filter string `%s'", kfiltstr); - if (key_encode(kd, &d, &kfilt)) - RETVAL = newSVpv(d.buf, d.len); - else - RETVAL = &PL_sv_undef; - dstr_destroy(&d); + if ((s = sym_next(i)) == 0) + XSRETURN_UNDEF; + RETVAL = newSVpvn(SYM_NAME(s), SYM_LEN(s)); OUTPUT: RETVAL +SV * +DESTROY(i) + Key_StructIter *i + CODE: + DESTROY(i); + XSRETURN_YES; + +MODULE = Catacomb PACKAGE = Catacomb::Key::Data + MODULE = Catacomb PACKAGE = Catacomb::Key::File PREFIX = key_ Key_File * -new(me, file, how) +new(me, file, how = KOPEN_READ, report = &PL_sv_undef) SV *me char *file unsigned how + SV *report CODE: RETVAL = CREATE(key_file); - if (key_open(RETVAL, file, how, warn_keyreporter, 0)) { + if (key_open(&RETVAL->kf, file, how, keyreport, report)) { DESTROY(RETVAL); RETVAL = 0; } @@ -530,75 +689,80 @@ SV * DESTROY(kf) Key_File *kf CODE: - key_close(kf); - DESTROY(kf); + keyfile_dec(kf); XSRETURN_UNDEF; KeyErr -merge(kf, name, fp) +merge(kf, name, fp, report = &PL_sv_undef) Key_File *kf char *name FILE *fp + SV *report CODE: - RETVAL = key_merge(kf, name, fp, warn_keyreporter, 0); + RETVAL = key_merge(&kf->kf, name, fp, keyreport, report); OUTPUT: RETVAL bool -extract(kf, k, fp, kfiltstr = 0) +key_extract(kf, k, fp, kfilt = 0) Key_File *kf Key *k FILE *fp - char *kfiltstr - PREINIT: - key_filter kfilt; - CODE: - if (!kfiltstr) - kfilt.f = kfilt.m = 0; - else if (key_readflags(kfiltstr, 0, &kfilt.f, &kfilt.m)) - croak("bad filter string `%s'", kfiltstr); - RETVAL = key_extract(kf, k->k, fp, &kfilt); - OUTPUT: - RETVAL - -int -key_save(kf) - Key_File *kf + Key_Filter *kfilt + C_ARGS: + &kf->kf, k->k, fp, kfilt void -qtag(kf, tag) +qtag(kf, tag, kdnew = 0) Key_File *kf char *tag + Key_Data *kdnew PREINIT: dstr d = DSTR_INIT; - Key *k; - key_data *kd; + key_data **kd; + key_data *okd; + key *k; + Key *kk; PPCODE: - k = CREATE(Key); - kd = CREATE(key_data); - if (key_qtag(kf, tag, &d, &k->k, &kd)) { - DESTROY(k); - DESTROY(kd); - XPUSHs(&PL_sv_undef); - XPUSHs(&PL_sv_undef); - XPUSHs(&PL_sv_undef); - } else { - k->kf = kf; - XPUSHs(sv_2mortal(newSVpv(d.buf, d.len))); - XPUSHs(RET(k, "Catacomb::Key")); - XPUSHs(RET(k, "Catacomb::Key::Data")); + if (key_qtag(&kf->kf, tag, &d, &k, &kd)) { + keyerr(KERR_NOTFOUND); + XSRETURN_UNDEF; } + okd = *kd; + if (kdnew) { + if (!(kf->kf.f & KF_WRITE)) { + keyerr(KERR_READONLY); + XSRETURN_UNDEF; + } + kf->kf.f |= KF_MODIFIED; + *kd = kdnew; + } + key_incref(*kd); + kk = CREATE(Key); + kk->k = k; + kk->kf = kf; + kf->ref++; + XPUSHs(sv_2mortal(newSVpvn(d.buf, d.len))); + XPUSHs(RET(kk, "Catacomb::Key")); + XPUSHs(RET(okd, keydata_type(okd))); dstr_destroy(&d); +int +key_save(kf) + Key_File *kf + C_ARGS: + &kf->kf + Key * bytype(kf, type) Key_File *kf char *type CODE: RETVAL = CREATE(Key); - if ((RETVAL->k = key_bytype(kf, type)) != 0) + if ((RETVAL->k = key_bytype(&kf->kf, type)) != 0) { + kf->ref++; RETVAL->kf = kf; - else { + } else { DESTROY(RETVAL); RETVAL = 0; } @@ -611,9 +775,10 @@ byid(kf, id) U32 id CODE: RETVAL = CREATE(Key); - if ((RETVAL->k = key_byid(kf, id)) != 0) + if ((RETVAL->k = key_byid(&kf->kf, id)) != 0) { + kf->ref++; RETVAL->kf = kf; - else { + } else { DESTROY(RETVAL); RETVAL = 0; } @@ -626,28 +791,71 @@ bytag(kf, tag) char *tag CODE: RETVAL = CREATE(Key); - if ((RETVAL->k = key_bytag(kf, tag)) != 0) + if ((RETVAL->k = key_bytag(&kf->kf, tag)) != 0) { + kf->ref++; RETVAL->kf = kf; - else { + } else { DESTROY(RETVAL); RETVAL = 0; } OUTPUT: RETVAL -void -list(kf) +Key * +newkey(kf, id, type, exp = KEXP_FOREVER) Key_File *kf + U32 id + const char *type + time_t exp PREINIT: - key_iter i; - key *k; - Key *kk; - PPCODE: - for (key_mkiter(&i, kf); k = key_next(&i); ) { - kk = CREATE(Key); - kk->kf = kf; - kk->k = k; - XPUSHs(RET(kk, "Catacomb::Key")); + int err; + CODE: + RETVAL = CREATE(Key); + if ((err = key_new(&kf->kf, id, type, exp, &RETVAL->k)) == 0) { + DESTROY(RETVAL); + keyerr(err); + RETVAL = 0; + } else { + kf->ref++; + RETVAL->kf = kf; } + OUTPUT: + RETVAL + +Key_FileIter * +iterate(kf) + Key_File *kf + CODE: + RETVAL = CREATE(Key_FileIter); + key_mkiter(&RETVAL->i, &kf->kf); + RETVAL->kf = kf; + kf->ref++; + OUTPUT: + RETVAL + +MODULE = Catacomb PACKAGE = Catacomb::Key::FileIter + +Key * +next(ki) + Key_FileIter *ki + CODE: + RETVAL = CREATE(Key); + if ((RETVAL->k = key_next(&ki->i)) == 0) { + DESTROY(RETVAL); + RETVAL = 0; + } else { + RETVAL->kf = ki->kf; + ki->kf->ref++; + } + OUTPUT: + RETVAL + +SV * +DESTROY(ki) + Key_FileIter *ki + CODE: + keyfile_dec(ki->kf); + DESTROY(ki); + XSRETURN_YES; #----- That's all, folks ----------------------------------------------------