+static inline int isctrlchr(int c)
+{
+ if (c == 9) return 0;
+ if (c >= 0 && c <= 31) return 1;
+ if (c == 127) return 1;
+ return 0;
+}
+
+static int getps_plain_filter(struct getpasswd_state *getps, char chr, size_t pos)
+{
+ int x;
+
+ x = getps_filter(getps, chr, pos);
+ if (x != 1) return x;
+
+ if (pos < getps->pwlen && !isctrlchr(chr))
+ write(getps->efd, &chr, sizeof(char));
+ return 1;
+}
+
+static int getps_plain_hex_filter(struct getpasswd_state *getps, char chr, size_t pos)
+{
+ int x;
+
+ x = getps_hex_filter(getps, chr, pos);
+ if (x != 1) return x;
+
+ if (pos < getps->pwlen && !isctrlchr(chr))
+ write(getps->efd, &chr, sizeof(char));
+ return 1;
+}
+
+static void make_hint(void *hint, size_t szhint, const void *data, size_t szdata)
+{
+ char t[TF_FROM_BITS(TF_MAX_BITS)];
+
+ skein(t, TF_MAX_BITS, NULL, data, szdata);
+ xor_shrink(hint, szhint, t, sizeof(t));
+ memset(t, 0, sizeof(t));
+}
+
+static void raw_say_hint(void *hint, size_t szhint, const void *data, size_t szdata, const char *prompt)
+{
+ make_hint(hint, szhint, data, szdata);
+ if (prompt) tfc_nfsay(stderr, "%s: ", prompt);
+ mehexdump(hint, szhint, szhint, 1);
+ memset(hint, 0, szhint);
+}
+
+static void say_hint(const void *data, size_t szdata, const char *prompt)
+{
+ char t[TF_SIZE_UNIT];
+ raw_say_hint(t, TF_SIZE_UNIT, data, szdata, prompt);
+ /* t[] is erased (automatically) */
+}
+