#include <string.h>
#include <mLib/dstr.h>
+#include <mLib/str.h>
#include <mLib/hex.h>
#include <mLib/base32.h>
/*----- File hashing ------------------------------------------------------*/
+/* --- @gethash@ --- *
+ *
+ * Arguments: @const char *name@ = pointer to name string
+ *
+ * Returns: Pointer to appropriate hash class.
+ *
+ * Use: Chooses a hash function by name.
+ */
+
+const gchash *gethash(const char *name)
+{
+ const gchash *const *g, *gg = 0;
+ size_t sz = strlen(name);
+ for (g = ghashtab; *g; g++) {
+ if (strncmp(name, (*g)->name, sz) == 0) {
+ if ((*g)->name[sz] == 0) {
+ gg = *g;
+ break;
+ } else if (gg)
+ return (0);
+ else
+ gg = *g;
+ }
+ }
+ return (gg);
+}
+
/* --- @fhash@ --- *
*
* Arguments: @const gchash *gch@ = pointer to hash function to use
return (rc);
}
+/* --- @hfparse@ --- *
+ *
+ * Arguments: @hfpctx *hfp@ = pointer to the context structure
+ *
+ * Returns: A code indicating what happened.
+ *
+ * Use: Parses a line from the input file.
+ */
+
+int hfparse(hfpctx *hfp)
+{
+ char *p, *q;
+ const gchash *gch;
+ const encodeops *ee;
+ dstr *d = hfp->dline;
+ size_t hsz;
+
+ /* --- Fetch the input line and get ready to parse --- */
+
+ DRESET(d);
+ if (dstr_putline(d, hfp->fp) == EOF) return (HF_EOF);
+ p = d->buf;
+
+ /* --- Parse magic comments --- */
+
+ if (*p == '#') {
+ p++;
+ if ((q = str_getword(&p)) == 0) return (HF_BAD);
+ if (strcmp(q, "hash") == 0) {
+ if ((q = str_getword(&p)) == 0) return (HF_BAD);
+ if ((gch = gethash(q)) == 0) return (HF_BAD);
+ hfp->gch = gch;
+ return (HF_HASH);
+ } else if (strcmp(q, "encoding") == 0) {
+ if ((q = str_getword(&p)) == 0) return (HF_BAD);
+ if ((ee = getencoding(q)) == 0) return (HF_BAD);
+ hfp->ee = ee;
+ return (HF_ENC);
+ } else if (strcmp(q, "escape") == 0) {
+ hfp->f |= HFF_ESCAPE;
+ return (HF_ESC);
+ }
+ return (HF_BAD);
+ }
+
+ /* --- Otherwise it's a file line --- */
+
+ q = p;
+ while (*p && *p != ' ') p++;
+ if (!*p) return (HF_BAD);
+ *p++ = 0;
+ hsz = hfp->gch->hashsz;
+ if (hfp->ee->get(q, hfp->hbuf, hsz, 0) < hsz) return (HF_BAD);
+ switch (*p) {
+ case '*': hfp->f |= FHF_BINARY; break;
+ case ' ': hfp->f &= ~FHF_BINARY; break;
+ default: return (HF_BAD);
+ }
+ p++;
+
+ DRESET(hfp->dfile);
+ if (hfp->f & HFF_ESCAPE)
+ getstring(&p, hfp->dfile, GSF_STRING);
+ else {
+ dstr_putm(hfp->dfile, p, d->len - (p - d->buf));
+ dstr_putz(hfp->dfile);
+ }
+
+ return (HF_FILE);
+}
+
/*----- String I/O --------------------------------------------------------*/
/* --- @getstring@ --- *