diff --git a/.gitattributes b/.gitattributes
index 694e699ea58ecb82e9f0b53c0b9a9aa8dddb1b8a..fe3afe58e94a91d649447c433cfd77d69f8efb76 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -18,6 +18,7 @@ testfont binary
 /NT/tools/install-sh foreign_ident
 /bin/export.pike foreign_ident
 /bin/httpd.pike foreign_ident
+/bin/make_ci.pike foreign_ident
 /bin/mkpeep.pike foreign_ident
 /bin/mkwmml.pike foreign_ident
 /bin/test_pike.pike foreign_ident
@@ -106,6 +107,7 @@ testfont binary
 /src/dmalloc.h foreign_ident
 /src/docode.c foreign_ident
 /src/docode.h foreign_ident
+/src/dummy_ci.h foreign_ident
 /src/dynamic_buffer.c foreign_ident
 /src/dynamic_buffer.h foreign_ident
 /src/dynamic_load.c foreign_ident
diff --git a/bin/make_ci.pike b/bin/make_ci.pike
new file mode 100644
index 0000000000000000000000000000000000000000..383e3903920e37e0a17b3487935a5d32b4b4360b
--- /dev/null
+++ b/bin/make_ci.pike
@@ -0,0 +1,91 @@
+/*
+ * $Id: make_ci.pike,v 1.1 1999/03/20 02:36:57 grubba Exp $
+ *
+ * Creates the file case_info.h
+ *
+ * Henrik Grubbström 1999-03-20
+ */
+
+#define CIM_NONE	0	/* Case-less */
+#define CIM_UPPER	1	/* Upper-case, lower-case in data */
+#define CIM_LOWER	2	/* Lower-case, upper-case in data */
+#define CIM_CASEBIT	3	/* Some case, case bit in data */
+#define CIM_CASEBITOFF	4	/* Same as above, but also offset by data */
+
+int main(int argc, array(string) argv)
+{
+  int lineno;
+  array(array(int)) ci = ({({ 0, CIM_NONE, 0 })});
+
+  string data = Stdio.stdin.read();
+
+  foreach(data/"\r\n", string line) {
+    lineno++;
+    array(string) info = line/";";
+
+    if (!sizeof(line)) continue;
+
+    if (sizeof(info) != 15) {
+      werror(sprintf("Syntax error on line %d: "
+		     "Bad number of fields:%d (expected 15)\n"
+		     "%O\n",
+		     lineno, sizeof(info), line));
+      exit(1);
+    }
+    int char;
+    sscanf(info[0], "%04x", char);
+    int mode = CIM_NONE;
+    int d;
+    if (sizeof(info[13])) {
+      // Upper-case char
+      mode = CIM_UPPER;
+      sscanf(info[13], "%04x", d);
+      int delta = d - char;
+      if (!(delta & (delta - 1)) && (delta > 0)) {
+	if (d & delta) {
+	  mode = CIM_CASEBIT;
+	} else {
+	  mode = CIM_CASEBITOFF;
+	}
+	d = delta;
+      }
+    } else if (sizeof(info[14])) {
+      // Lower-case char
+      mode = CIM_LOWER;
+      sscanf(info[14], "%04x", d);
+      int delta = char - d;
+      if (!(delta & (delta - 1)) && (delta > 0)) {
+	if (char & delta) {
+	  mode = CIM_CASEBIT;
+	} else {
+	  mode = CIM_CASEBITOFF;
+	}
+	d = delta;
+      }
+    }
+
+    if ((ci[-1][1] != mode) || (ci[-1][2] != d)) {
+      // New range.
+      ci += ({({ char, mode, d })});
+    }
+  }
+
+  write(sprintf("/*\n"
+		" * Created by $Id: make_ci.pike,v 1.1 1999/03/20 02:36:57 grubba Exp $ on %s"
+		" *\n"
+		" * Table used for looking up the case of\n"
+		" * Unicode characters.\n"
+		" *\n"
+		" * Henrik Grubbström 1999-03-20\n"
+		" */\n\n", ctime(time()));
+
+  foreach(ci, array(int) info) {
+    write(sprintf("{ 0x%04x, %s, 0x%04x, },\n",
+		  info[0],
+		  ({ "CIM_NONE", "CIM_UPPER", "CIM_LOWER",
+		     "CIM_CASEBIT", "CIM_CASEBITOFF" })[info[1]],
+		  info[2]));
+  }
+
+  exit(0);
+}
diff --git a/src/dummy_ci.h b/src/dummy_ci.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d29a75e359550e5e94c938f6597fa17bb214260
--- /dev/null
+++ b/src/dummy_ci.h
@@ -0,0 +1,21 @@
+/*
+ * $Id: dummy_ci.h,v 1.1 1999/03/20 02:30:37 grubba Exp $
+ *
+ * Fallback case_info file.
+ * Only ISO-8859-1 in this one.
+ *
+ * Henrik Grubbström 1999-03-20
+ */
+{ 0x0000, CIM_NONE, 0x0000, },
+{ 0x0041, CIM_CASEBIT, 0x0020, },
+{ 0x005b, CIM_NONE, 0x0000, },
+{ 0x0061, CIM_CASEBIT, 0x0020, },
+{ 0x007b, CIM_NONE, 0x0000, },
+{ 0x00c0, CIM_CASEBIT, 0x0020, },
+{ 0x00d7, CIM_NONE, 0x0000, },
+{ 0x00d8, CIM_CASEBIT, 0x0020, },
+{ 0x00df, CIM_NONE, 0x0000, },
+{ 0x00e0, CIM_CASEBIT, 0x0020, },
+{ 0x00f7, CIM_NONE, 0x0000, },
+{ 0x00f8, CIM_CASEBIT, 0x0020, },
+{ 0x00ff, CIM_LOWER, 0x0178, },