+void
+qtag(kf, tag, kdnew = 0)
+ Key_File *kf
+ char *tag
+ Key_Data *kdnew
+ PREINIT:
+ dstr d = DSTR_INIT;
+ key_data **kd;
+ key_data *okd;
+ key *k;
+ Key *kk;
+ PPCODE:
+ 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);
+