chiark / gitweb /
Greetings and challenges.
[tripe] / servutil.c
index 590327db4ad36aa368133c90bda98fb40fe82060..f4ab92e376667334c93a2aefdd5c71427090d07e 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: servutil.c,v 1.5 2004/04/08 01:36:17 mdw Exp $
+ * $Id$
  *
  * Various handy server-only utilities
  *
@@ -91,4 +91,74 @@ const char *timestr(time_t t)
   return ((const char *)buf_t);
 }
 
+/* --- @b64_encode@ --- *
+ *
+ * Arguments:  @const void *p@ = pointer to some gorp
+ *             @size_t sz@ = size of the gorp
+ *
+ * Returns:    Pointer to base64-encoded version in @buf_t@.
+ */
+
+const char *b64_encode(const void *p, size_t sz)
+{
+  base64_ctx b64;
+  dstr d = DSTR_INIT;
+
+  base64_init(&b64);
+  b64.indent = "";
+  b64.maxline = 0;
+  base64_encode(&b64, p, sz, &d);
+  base64_encode(&b64, 0, 0, &d);
+  while (d.len && d.buf[d.len - 1] == '=') d.len--;
+  assert(d.len < sizeof(buf_t));
+  memcpy(buf_t, d.buf, d.len);
+  buf_t[d.len] = 0;
+  dstr_destroy(&d);
+  return ((const char *)buf_t);
+}
+
+/* --- @seq_reset@ --- *
+ *
+ * Arguments:  @seqwin *s@ = sequence-checking window
+ *
+ * Returns:    ---
+ *
+ * Use:                Resets a sequence number window.
+ */
+
+void seq_reset(seqwin *s) { s->seq = 0; s->win = 0; }
+
+/* --- @seq_check@ --- *
+ *
+ * Arguments:  @seqwin *s@ = sequence-checking window
+ *             @uint32 q@ = sequence number to check
+ *
+ * Returns:    A @SEQ_@ code.
+ *
+ * Use:                Checks a sequence number against the window, updating things
+ *             as necessary.
+ */
+
+int seq_check(seqwin *s, uint32 q)
+{
+  uint32 qbit;
+  uint32 n;
+
+  if (q < s->seq)
+    return (SEQ_OLD);
+  if (q >= s->seq + SEQ_WINSZ) {
+    n = q - (s->seq + SEQ_WINSZ - 1);
+    if (n < SEQ_WINSZ)
+      s->win >>= n;
+    else
+      s->win = 0;
+    s->seq += n;
+  }
+  qbit = 1 << (q - s->seq);
+  if (s->win & qbit)
+    return (SEQ_REPLAY);
+  s->win |= qbit;
+  return (0);
+}
+
 /*----- That's all, folks -------------------------------------------------*/