aboutsummaryrefslogtreecommitdiff
path: root/ircd/s_id.c
diff options
context:
space:
mode:
Diffstat (limited to 'ircd/s_id.c')
-rw-r--r--ircd/s_id.c208
1 files changed, 208 insertions, 0 deletions
diff --git a/ircd/s_id.c b/ircd/s_id.c
new file mode 100644
index 0000000..5feb948
--- /dev/null
+++ b/ircd/s_id.c
@@ -0,0 +1,208 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, ircd/s_id.c
+ * Copyright (C) 1998 Christophe Kalt
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: s_id.c,v 1.9 1999/07/27 11:26:37 chopin Exp $";
+#endif
+
+#include "os.h"
+#include "s_defines.h"
+#define S_ID_C
+#include "s_externs.h"
+#undef S_ID_C
+
+/*
+ * channel IDs
+ */
+#define CHIDNB 36
+
+static unsigned char id_alphabet[CHIDNB+1] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890A";
+
+static unsigned int alphabet_id[256] =
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ /* 0 */ 35, /* 1 */ 26, /* 2 */ 27, /* 3 */ 28, /* 4 */ 29,
+ /* 5 */ 30, /* 6 */ 31, /* 7 */ 32, /* 8 */ 33, /* 9 */ 34,
+ -1, -1, -1, -1, -1, -1, -1,
+ /* A */ 0, /* B */ 1, /* C */ 2, /* D */ 3, /* E */ 4, /* F */ 5,
+ /* G */ 6, /* H */ 7, /* I */ 8, /* J */ 9, /* K */ 10, /* L */ 11,
+ /* M */ 12, /* N */ 13, /* O */ 14, /* P */ 15, /* Q */ 16,
+ /* R */ 17, /* S */ 18, /* T */ 19, /* U */ 20, /* V */ 21,
+ /* W */ 22, /* X */ 23, /* Y */ 24, /* Z */ 25,
+ -1, -1, -1, -1, -1, -1,
+ /* a */ 0, /* b */ 1, /* c */ 2, /* d */ 3, /* e */ 4, /* f */ 5,
+ /* g */ 6, /* h */ 7, /* i */ 8, /* j */ 9, /* k */ 10, /* l */ 11,
+ /* m */ 12, /* n */ 13, /* o */ 14, /* p */ 15, /* q */ 16,
+ /* r */ 17, /* s */ 18, /* t */ 19, /* u */ 20, /* v */ 21,
+ /* w */ 22, /* x */ 23, /* y */ 24, /* z */ 25,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1 };
+
+/* ltoid: base 10 -> base 36 conversion */
+static char *
+ltoid(l)
+time_t l;
+{
+ static char idrpl[CHIDLEN+1];
+ char c = CHIDLEN-1;
+
+ idrpl[CHIDLEN] = '\0';
+ do
+ {
+ idrpl[c] = id_alphabet[1 + l % CHIDNB];
+ l /= CHIDNB;
+ }
+ while (c-- > 0);
+ return (char *) idrpl;
+}
+
+/* idtol: base 36 -> base 10 conversion */
+static unsigned long
+idtol(id)
+char *id;
+{
+ unsigned long l = 0;
+ char c = CHIDLEN-1;
+
+ l = alphabet_id[*id++];
+ while (c-- > 0)
+ l = l * CHIDNB + alphabet_id[*id++];
+ return l;
+}
+
+/* get_chid: give the current id */
+char *
+get_chid()
+{
+ return ltoid(time(NULL));
+}
+
+/* close_chid: is the ID in the close future? (written for CHIDLEN == 5) */
+int
+close_chid(id)
+char *id;
+{
+ static time_t last = 0;
+ static char current;
+ char *curid;
+
+ if (timeofday - last > 900 || id[0] == current)
+ {
+ last = timeofday;
+ curid = get_chid();
+ current = curid[0];
+ }
+ if (id_alphabet[1 + alphabet_id[current]] == id[1])
+ return 1;
+ if (id[0] == current &&
+ idtol(id) >= (timeofday % (u_int) pow(CHIDNB, CHIDLEN)))
+ return 1;
+ return 0;
+}
+
+aChannel *idcache = NULL;
+
+/* cache_chid: add a channel to the list of cached names */
+void
+cache_chid(chptr)
+aChannel *chptr;
+{
+ /*
+ ** caching should be limited to the minimum,
+ ** for memory reasons, but most importantly for
+ ** user friendly-ness.
+ ** Is the logic here right, tho?
+ */
+ if (chptr->history == 0 ||
+ (timeofday - chptr->history) >LDELAYCHASETIMELIMIT+DELAYCHASETIMELIMIT)
+ {
+ MyFree((char *)chptr);
+ return;
+ }
+
+ chptr->nextch = idcache;
+ idcache = chptr;
+ istat.is_cchan++;
+ istat.is_cchanmem -= sizeof(aChannel) + strlen(chptr->chname);
+}
+
+/* check_chid: checks if a (short) channel name is in the cache
+ * returns: 0 if not, 1 if yes
+ */
+int
+check_chid(name)
+char *name;
+{
+ aChannel *chptr = idcache;
+
+ while (chptr)
+ {
+ if (!strcasecmp(name, chptr->chname+1+CHIDLEN))
+ return 1;
+ chptr = chptr->nextch;
+ }
+ return 0;
+}
+
+/* collect_chid: remove expired entries from the cache */
+void
+collect_chid()
+{
+ aChannel **chptr = &idcache, *del;
+
+ while (*chptr)
+ {
+ if (close_chid((*chptr)->chname) == 0)
+ {
+ del = *chptr;
+ *chptr = del->nextch;
+ istat.is_cchan--;
+ istat.is_cchanmem -= sizeof(aChannel) +strlen(del->chname);
+ MyFree((char *)del);
+ }
+ else
+ chptr = &((*chptr)->nextch);
+ }
+}
+
+/* checks wether the ID is valid */
+int
+cid_ok(name)
+char *name;
+{
+ int l = 1;
+
+ while (l <= CHIDLEN)
+ {
+ if (alphabet_id[name[l]] == -1)
+ return 0;
+ l += 1;
+ }
+ if (l != CHIDLEN+1)
+ return 0;
+ return 1;
+}