return (0);
if (tag) *tag = SYM_NAME(ks);
if (kd) *kd = ks->k;
+ return (1);
}
/* --- @key_structset@, @key_structsteal@ --- *
}
}
+/* --- @key_copydata@ --- *
+ *
+ * Arguments: @key_data *k@ = key data to copy
+ * @const key_filter *kf@ = pointer to filter block
+ *
+ * Returns: Pointer to a copy of the data, or null if the root subkey
+ * didn't match the filter.
+ *
+ * Use: Copies a chunk of key data. Subkeys, whether they're
+ * structured or leaves, which don't match the filter aren't
+ * copied. The copy may or may not have structure in common
+ * with the original.
+ */
+
+static int structmatchp(key_data *k, const key_filter *kf)
+{
+ key_subkeyiter i;
+
+ if (!KEY_MATCH(k, kf)) return (0);
+ else if ((k->e & KF_ENCMASK) == KENC_STRUCT) return (1);
+ else {
+ for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, 0, &k); )
+ if (!structmatchp(k, kf)) return (0);
+ return (1);
+ }
+}
+
+key_data *key_copydata(key_data *k, const key_filter *kf)
+{
+ key_subkeyiter i;
+ const char *tag;
+ key_data *kd, *kkd;
+
+ /* --- Trivial cases --- */
+
+ if (!KEY_MATCH(k, kf))
+ return (0);
+ else if (structmatchp(k, kf)) {
+ key_incref(k);
+ return (k);
+ }
+
+ /* --- Copy a structured key recursively --- */
+
+ kkd = key_newstruct();
+ for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, &tag, &kd); ) {
+ if ((kd = key_copydata(kd, kf)) != 0)
+ key_structsteal(kkd, tag, kd);
+ }
+
+ /* --- Done --- */
+
+ return (kkd);
+}
+
/*----- That's all, folks -------------------------------------------------*/