return (0);
}
+/*----- Rate limiting -----------------------------------------------------*/
+
+/* --- @ratelim_init@ --- *
+ *
+ * Arguments: @ratelim *r@ = rate-limiting state to fill in
+ * @unsigned persec@ = credit to accumulate per second
+ * @unsigned max@ = maximum credit to retain
+ *
+ * Returns: ---
+ *
+ * Use: Initialize a rate-limiting state.
+ */
+
+void ratelim_init(ratelim *r, unsigned persec, unsigned max)
+{
+ r->n = r->max = max;
+ r->persec = persec;
+ gettimeofday(&r->when, 0);
+}
+
+/* --- @ratelim_withdraw@ --- *
+ *
+ * Arguments: @ratelim *r@ = rate-limiting state
+ * @unsigned n@ = credit to withdraw
+ *
+ * Returns: Zero if successful; @-1@ if there is unsufficient credit
+ *
+ * Use: Updates the state with any accumulated credit. Then, if
+ * there there are more than @n@ credits available, withdraw @n@
+ * and return successfully; otherwise, report failure.
+ */
+
+int ratelim_withdraw(ratelim *r, unsigned n)
+{
+ struct timeval now, delta;
+ unsigned long d;
+
+ gettimeofday(&now, 0);
+ TV_SUB(&delta, &now, &r->when);
+ d = (unsigned long)r->persec*delta.tv_sec +
+ (unsigned long)r->persec*delta.tv_usec/MILLION;
+ if (d < r->max - r->n) r->n += d;
+ else r->n = r->max;
+ r->when = now;
+
+ if (n > r->n) return (-1);
+ else { r->n -= n; return (0); }
+}
+
/*----- Random odds and sods ----------------------------------------------*/
/* --- @timestr@ --- *
extern int seq_check(seqwin */*s*/, uint32 /*q*/, const char */*service*/);
+typedef struct ratelim {
+ unsigned n, max, persec;
+ struct timeval when;
+} ratelim;
+
+/* --- @ratelim_init@ --- *
+ *
+ * Arguments: @ratelim *r@ = rate-limiting state to fill in
+ * @unsigned persec@ = credit to accumulate per second
+ * @unsigned max@ = maximum credit to retain
+ *
+ * Returns: ---
+ *
+ * Use: Initialize a rate-limiting state.
+ */
+
+extern void ratelim_init(ratelim */*r*/,
+ unsigned /*persec*/, unsigned /*max*/);
+
+/* --- @ratelim_withdraw@ --- *
+ *
+ * Arguments: @ratelim *r@ = rate-limiting state
+ * @unsigned n@ = credit to withdraw
+ *
+ * Returns: Zero if successful; @-1@ if there is unsufficient credit
+ *
+ * Use: Updates the state with any accumulated credit. Then, if
+ * there there are more than @n@ credits available, withdraw @n@
+ * and return successfully; otherwise, report failure.
+ */
+
+extern int ratelim_withdraw(ratelim */*r*/, unsigned /*n*/);
+
/*----- That's all, folks -------------------------------------------------*/
#ifdef __cplusplus