Merge branch 'master' into gtk3
[projects/chimara/chimara.git] / babel / adrift.c
1 /* adrift.c  Treaty of Babel module for Adrift files\r
2  *\r
3  * PROVISIONAL - Hold for someone else\r
4  *\r
5  * This file depends on treaty_builder.h\r
6  *\r
7  * This file is public domain, but note that any changes to this file\r
8  * may render it noncompliant with the Treaty of Babel\r
9  */\r
10 \r
11 #define FORMAT adrift\r
12 #define HOME_PAGE "http://www.adrift.org.uk"\r
13 #define FORMAT_EXT ".taf"\r
14 #define NO_METADATA\r
15 #define NO_COVER\r
16 \r
17 #include "treaty_builder.h"\r
18 \r
19 #include <stdio.h>\r
20 #include <limits.h>\r
21 #include <stdlib.h>\r
22 \r
23 /* VB RNG constants */\r
24 #define  VB_RAND1      0x43FD43FD\r
25 #define  VB_RAND2      0x00C39EC3\r
26 #define  VB_RAND3      0x00FFFFFF\r
27 #define  VB_INIT       0x00A09E86\r
28 static int32 vbr_state;\r
29 \r
30 /*\r
31   Unobfuscates one byte from a taf file. This should be called on each byte\r
32   in order, as the ADRIFT obfuscation function is stately.\r
33 \r
34   The de-obfuscation algorithm works by xoring the byte with the next\r
35   byte in the sequence produced by the Visual Basic pseudorandom number\r
36   generator, which is simulated here.\r
37 */\r
38 static unsigned char taf_translate (unsigned char c)\r
39 {\r
40  int32 r;\r
41 \r
42  vbr_state = (vbr_state*VB_RAND1+VB_RAND2) & VB_RAND3;\r
43  r=UCHAR_MAX * (unsigned) vbr_state;\r
44  r/=((unsigned) VB_RAND3)+1;\r
45  return r^c;\r
46 }\r
47 \r
48 static int32 get_story_file_IFID(void *story_file, int32 extent, char *output, int32 output_extent)\r
49 {\r
50  int adv;\r
51  unsigned char buf[4];\r
52  unsigned char *sf=(unsigned char *)story_file;\r
53  vbr_state=VB_INIT;\r
54 \r
55  if (extent <12) return INVALID_STORY_FILE_RV;\r
56 \r
57  buf[3]=0;\r
58  /* Burn the first 8 bytes of translation */\r
59  for(adv=0;adv<8;adv++) taf_translate(0);\r
60  /* Bytes 8-11 contain the Adrift version number in the formay N.NN */\r
61  buf[0]=taf_translate(sf[8]);\r
62  taf_translate(0);\r
63  buf[1]=taf_translate(sf[10]);\r
64  buf[2]=taf_translate(sf[11]);\r
65  adv=atoi((char *) buf);\r
66  ASSERT_OUTPUT_SIZE(12);\r
67  sprintf(output,"ADRIFT-%03d-",adv);\r
68  return INCOMPLETE_REPLY_RV;\r
69 \r
70 }\r
71 \r
72 /* The claim algorithm for ADRIFT is to unobfuscate the first\r
73    seven bytes, and check for the word "Version".\r
74    It seems fairly unlikely that the obfuscated form of that\r
75    word would occur in the wild\r
76 */\r
77 static int32 claim_story_file(void *story_file, int32 extent)\r
78 {\r
79  unsigned char buf[8];\r
80  int i;\r
81  unsigned char *sf=(unsigned char *)story_file;\r
82  buf[7]=0;\r
83  vbr_state=VB_INIT;\r
84  if (extent<12) return INVALID_STORY_FILE_RV;\r
85  for(i=0;i<7;i++) buf[i]=taf_translate(sf[i]);\r
86  if (strcmp((char *)buf,"Version")) return INVALID_STORY_FILE_RV;\r
87  return VALID_STORY_FILE_RV;\r
88 \r
89 }\r