Merge branch 'master' into browser
[projects/chimara/chimara.git] / babel / adrift.c
diff --git a/babel/adrift.c b/babel/adrift.c
new file mode 100644 (file)
index 0000000..3718d6a
--- /dev/null
@@ -0,0 +1,89 @@
+/* adrift.c  Treaty of Babel module for Adrift files\r
+ *\r
+ * PROVISIONAL - Hold for someone else\r
+ *\r
+ * This file depends on treaty_builder.h\r
+ *\r
+ * This file is public domain, but note that any changes to this file\r
+ * may render it noncompliant with the Treaty of Babel\r
+ */\r
+\r
+#define FORMAT adrift\r
+#define HOME_PAGE "http://www.adrift.org.uk"\r
+#define FORMAT_EXT ".taf"\r
+#define NO_METADATA\r
+#define NO_COVER\r
+\r
+#include "treaty_builder.h"\r
+\r
+#include <stdio.h>\r
+#include <limits.h>\r
+#include <stdlib.h>\r
+\r
+/* VB RNG constants */\r
+#define  VB_RAND1      0x43FD43FD\r
+#define  VB_RAND2      0x00C39EC3\r
+#define  VB_RAND3      0x00FFFFFF\r
+#define  VB_INIT       0x00A09E86\r
+static int32 vbr_state;\r
+\r
+/*\r
+  Unobfuscates one byte from a taf file. This should be called on each byte\r
+  in order, as the ADRIFT obfuscation function is stately.\r
+\r
+  The de-obfuscation algorithm works by xoring the byte with the next\r
+  byte in the sequence produced by the Visual Basic pseudorandom number\r
+  generator, which is simulated here.\r
+*/\r
+static unsigned char taf_translate (unsigned char c)\r
+{\r
+ int32 r;\r
+\r
+ vbr_state = (vbr_state*VB_RAND1+VB_RAND2) & VB_RAND3;\r
+ r=UCHAR_MAX * (unsigned) vbr_state;\r
+ r/=((unsigned) VB_RAND3)+1;\r
+ return r^c;\r
+}\r
+\r
+static int32 get_story_file_IFID(void *story_file, int32 extent, char *output, int32 output_extent)\r
+{\r
+ int adv;\r
+ unsigned char buf[4];\r
+ unsigned char *sf=(unsigned char *)story_file;\r
+ vbr_state=VB_INIT;\r
+\r
+ if (extent <12) return INVALID_STORY_FILE_RV;\r
+\r
+ buf[3]=0;\r
+ /* Burn the first 8 bytes of translation */\r
+ for(adv=0;adv<8;adv++) taf_translate(0);\r
+ /* Bytes 8-11 contain the Adrift version number in the formay N.NN */\r
+ buf[0]=taf_translate(sf[8]);\r
+ taf_translate(0);\r
+ buf[1]=taf_translate(sf[10]);\r
+ buf[2]=taf_translate(sf[11]);\r
+ adv=atoi((char *) buf);\r
+ ASSERT_OUTPUT_SIZE(12);\r
+ sprintf(output,"ADRIFT-%03d-",adv);\r
+ return INCOMPLETE_REPLY_RV;\r
+\r
+}\r
+\r
+/* The claim algorithm for ADRIFT is to unobfuscate the first\r
+   seven bytes, and check for the word "Version".\r
+   It seems fairly unlikely that the obfuscated form of that\r
+   word would occur in the wild\r
+*/\r
+static int32 claim_story_file(void *story_file, int32 extent)\r
+{\r
+ unsigned char buf[8];\r
+ int i;\r
+ unsigned char *sf=(unsigned char *)story_file;\r
+ buf[7]=0;\r
+ vbr_state=VB_INIT;\r
+ if (extent<12) return INVALID_STORY_FILE_RV;\r
+ for(i=0;i<7;i++) buf[i]=taf_translate(sf[i]);\r
+ if (strcmp((char *)buf,"Version")) return INVALID_STORY_FILE_RV;\r
+ return VALID_STORY_FILE_RV;\r
+\r
+}\r