aboutsummaryrefslogtreecommitdiff
path: root/libio/dbz/case.c
diff options
context:
space:
mode:
Diffstat (limited to 'libio/dbz/case.c')
-rw-r--r--libio/dbz/case.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/libio/dbz/case.c b/libio/dbz/case.c
new file mode 100644
index 00000000000..87b741ff54a
--- /dev/null
+++ b/libio/dbz/case.c
@@ -0,0 +1,129 @@
+/*
+ * case-mapping stuff
+ *
+ * We exploit the fact that we are dealing only with headers here, and
+ * headers are limited to the ASCII characters by RFC822. It is barely
+ * possible that we might be dealing with a translation into another
+ * character set, but in particular it's very unlikely for a header
+ * character to be outside -128..255.
+ *
+ * Life would be a whole lot simpler if tolower() could safely and portably
+ * be applied to any char.
+ */
+#include <stdio.h>
+#include "string.h"
+#include "case.h"
+
+/* note that case.h knows the value of OFFSET */
+#define OFFSET 128 /* avoid trouble with negative chars */
+#define MAPSIZE (256+OFFSET)
+char casemap[MAPSIZE]; /* relies on init to '\0' */
+static int primed = 0; /* has casemap been set up? */
+
+/*
+ - prime - set up case-mapping stuff
+ */
+static void
+prime()
+{
+ register char *lp;
+ register char *up;
+ register int c;
+ register int i;
+ static char lower[] = "abcdefghijklmnopqrstuvwxyz";
+ static char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ for (lp = lower, up = upper; *lp != '\0'; lp++, up++) {
+ c = *lp;
+ casemap[c+OFFSET] = c;
+ casemap[*up+OFFSET] = c;
+ }
+ for (i = 0; i < MAPSIZE; i++)
+ if (casemap[i] == '\0')
+ casemap[i] = (char)(i-OFFSET);
+ primed = 1;
+}
+
+/*
+ - cistrncmp - case-independent strncmp
+ */
+int /* < == > 0 */
+cistrncmp(s1, s2, len)
+char *s1;
+char *s2;
+int len;
+{
+ register char *p1;
+ register char *p2;
+ register int n;
+
+ if (!primed)
+ prime();
+
+ p1 = s1;
+ p2 = s2;
+ n = len;
+ while (--n >= 0 && *p1 != '\0' && TOLOW(*p1) == TOLOW(*p2)) {
+ p1++;
+ p2++;
+ }
+ if (n < 0)
+ return(0);
+
+ /*
+ * The following case analysis is necessary so that characters
+ * which look negative collate low against normal characters but
+ * high against the end-of-string NUL.
+ */
+ if (*p1 == '\0' && *p2 == '\0')
+ return(0);
+ else if (*p1 == '\0')
+ return(-1);
+ else if (*p2 == '\0')
+ return(1);
+ else
+ return(TOLOW(*p1) - TOLOW(*p2));
+}
+
+/*
+ - rfc822ize - do the bizarre case conversion needed for rfc822 message-ids
+ *
+ * Actually, this is not quite complete. Absolute, total, full RFC822
+ * compliance requires a horrible parsing job, because of the arcane
+ * quoting conventions -- abc"def"ghi is not equivalent to abc"DEF"ghi,
+ * for example. There are three or four things that might occur in the
+ * domain part of a message-id that are case-sensitive. They don't seem
+ * to ever occur in real news, thank Cthulhu. (What? You were expecting
+ * a merciful and forgiving deity to be invoked in connection with RFC822?
+ * Forget it; none of them would come near it.)
+ */
+char * /* returns the argument */
+rfc822ize(s)
+char *s;
+{
+ register char *p;
+ static char post[] = "postmaster";
+ static int postlen = sizeof(post)-1;
+
+ if (!primed)
+ prime();
+
+ p = strrchr(s, '@');
+ if (p == NULL) /* no local/domain split */
+ p = ""; /* assume all local */
+ else if (p - (s+1) == postlen && CISTREQN(s+1, post, postlen)) {
+ /* crazy special case -- "postmaster" is case-insensitive */
+ p = s;
+ }
+#ifdef NONSTANDARD
+#ifdef RFCVIOLATION
+#ifdef B_2_11_MISTAKE
+ p = s; /* all case-insensitive */
+#endif
+#endif
+#endif
+ for (; *p != '\0'; p++)
+ *p = TOLOW(*p);
+
+ return(s);
+}