From: Philip Chimento Date: Sat, 15 Sep 2012 15:38:07 +0000 (+0200) Subject: Remove Babel library from codebase X-Git-Tag: v0.9~13^2~2 X-Git-Url: https://git.stderr.nl/gitweb?p=projects%2Fchimara%2Fchimara.git;a=commitdiff_plain;h=8be24a16f55049419bd9481f1918729f269e56dc Remove Babel library from codebase Since we are going to release the library with a minimal player, and work together with Grotesque to produce a cool player, we are removing the Babel library for now. --- diff --git a/Makefile.am b/Makefile.am index a43dbac..352b3d3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,9 +2,9 @@ ## Created by Anjuta if TARGET_ILIAD -SUBDIRS = libchimara interpreters babel player po +SUBDIRS = libchimara interpreters player po else -SUBDIRS = libchimara interpreters babel player tests docs po +SUBDIRS = libchimara interpreters player tests docs po endif chimaradocdir = $(datadir)/doc/chimara diff --git a/babel/MANIFEST b/babel/MANIFEST deleted file mode 100644 index 09048bd..0000000 --- a/babel/MANIFEST +++ /dev/null @@ -1,51 +0,0 @@ -adrift.c Treaty of Babel module for Adrift -advsys.c Treaty of Babel module for AdvSys -alan.c Treaty of Babel module for Alan -agt.c Treaty of Babel module for AGT -babel.h babel program header -md5.h L. Peter Deutsch's md5 header -modules.h babel module registry -treaty.h Treaty of Babel header -treaty_builder.h Macros to build treaty modules -babel.c Babel main program -babel_handler.h Babel handler header file -babel_handler.c The babel handler api -babel_ifiction_functions.c Babel program-specific ifiction operations -babel_multi_functions.c Babel program-specific multi operations -babel_story_functions.c Babel program-specific story operations -blorb.c babel handler blorb module -executable.c Treaty of Bable module for executables -glulx.c Treaty of Babel module for glulx -hugo.c Draft Treaty of Babel module for hugo -ifiction.h babel ifiction header -ifiction.c babel ifiction api -level9.c Treaty of Babel module for level9 -magscrolls.c Magnetic Scrolls treaty module -makefile Provisional makefile -md5.c L. Peter Deutsch's md5 implementation -misc.c babel memory allocator -register.c babel module registry -register_ifiction.c babel module registry for ifiction API -tads.h Prototypes for tads2.c and tads3.c -tads.c Common functions for TADS modules -tads2.c Treaty of Babel module for tads2 -tads3.c Treaty of Babel module for tads3 -zcode.c Treaty of Babel module for zcode -README documentation -MANIFEST this file -extras/babel-cache.pl Perl demo of babel interaction -extras/babel-infocom.pl Special bundler for the infocom corpus -extras/babel-list.c Babel API demo -extras/babel-marry.pl Perl simple blorb encapsulator -extras/babel-wed.pl Perl single file blorb encapsulator -extras/hotload.c Dynamic loader replacement for register.c -extras/hotload.h Header file for hotload.c -extras/ifiction-aggregate.c Utility to combine multiple ifiction files -extras/ifiction-xtract.c Ifiction API demo -extras/simple-marry.c Simplified C version of babel-marry -babel-get/babel-get.c The babel-get application -babel-get/get_dir.c Directory source -babel-get/get_ifiction.c ifiction source -babel-get/get_story.c story file source -babel-get/get_url.c URL source -babel-get/makefile Makefile for babel-get diff --git a/babel/Makefile.am b/babel/Makefile.am deleted file mode 100644 index 1e0d78d..0000000 --- a/babel/Makefile.am +++ /dev/null @@ -1,36 +0,0 @@ -noinst_LTLIBRARIES = libbabel.la libifiction.la libbabel_functions.la - -libbabel_la_SOURCES = babel_handler.c \ - register.c \ - misc.c \ - md5.c \ - zcode.c \ - magscrolls.c \ - blorb.c \ - glulx.c \ - hugo.c \ - agt.c \ - level9.c \ - executable.c \ - advsys.c \ - tads.c \ - tads2.c \ - tads3.c \ - adrift.c \ - alan.c \ - babel.h \ - babel_handler.h \ - md5.h \ - modules.h \ - tads.h \ - treaty_builder.h \ - treaty.h - -libifiction_la_SOURCES = ifiction.c ifiction.h \ - register_ifiction.c - -libbabel_functions_la_SOURCES = babel_story_functions.c \ - babel_ifiction_functions.c \ - babel_multi_functions.c - --include $(top_srcdir)/git.mk diff --git a/babel/README b/babel/README deleted file mode 100644 index b754cab..0000000 --- a/babel/README +++ /dev/null @@ -1,74 +0,0 @@ -Version 0.2b, Treaty of Babel Revision 7 -This is the source code for babel, the Treaty of Babel analysis tool. - -Most of this code is (c) 2006 by L. Ross Raszewski - -The following files are public domain: -zcode.c -glulx.c -executable.c -level9.c -magscrolls.c -agt.c -hugo.c -advsys.c -misc.c -alan.c -adrift.c -treaty.h -treaty_builder.h - -The following files are Copyright (C) 1999, 2000, 2002 Aladdin Enterprises: -md5.c -md5.h - -And are used in accordance with their licenses. - -All other files are (c) 2006 by L. Ross Raszewski and are released under -the Creative Commons Attribution2.5 License. - -To view a copy of this license, visit -http://creativecommons.org/licenses/by/2.5/ or send a letter to - -Creative Commons, -543 Howard Street, 5th Floor, -San Francisco, California, 94105, USA. - - -To build babel: - -1. compile all the source files in this directory -2. link them together -3. the end - -For folks who find makefiles more useful than generalizations, there is a -makefile provided for babel. The makefile is currently configured for -Borland's 32-bit C compiler. Comment out those lines and uncomment the block -which follows for gcc. - -To compile babel-get, first compile babel, then do the same thing in the -babel-get directory. - -To compile ifiction-aggregate, ifiction-xtract, babel-list, and simple-marry, -first compile babel, then compile the relevant C file in the extras/ directory -(These may rely on #include files from the babel directory, so, for example, -to compile ifiction-aggregate, "gcc -c -I.. ifiction-aggregate.c"), then link the -opbject file to the babel and ifiction libraries (babel.lib and ifiction.lib -under Windows, babel.a and ifiction.a most everywhere else. eg. -"gcc -o ifiction-aggregate ifiction-aggregate.o ../babel.a ../ifiction.a") - -Babel is intended to accept contributions in the form of treaty modules -as defined by the treaty of babel section 2.3.2. - -These modules should use the declarations made in treaty.h. -The file treaty_builder.h generates a generic framework which simplifies -the task of writing treaty modules. Its use is not required for treaty -compliance, but it should prove useful. - -Parts of babel are intended for use in other programs. When adapting -babel's source, the files babel.c, babel_story_functions.c and -babel_ifiction_functions.c will probably not prove useful. However, you -may wish to use babel_handler, which provides a framework for loading a -story file, selecting the proper treaty modules, and seamlessly handling -blorb-wrapped files. - diff --git a/babel/adrift.c b/babel/adrift.c deleted file mode 100644 index 3718d6a..0000000 --- a/babel/adrift.c +++ /dev/null @@ -1,89 +0,0 @@ -/* adrift.c Treaty of Babel module for Adrift files - * - * PROVISIONAL - Hold for someone else - * - * This file depends on treaty_builder.h - * - * This file is public domain, but note that any changes to this file - * may render it noncompliant with the Treaty of Babel - */ - -#define FORMAT adrift -#define HOME_PAGE "http://www.adrift.org.uk" -#define FORMAT_EXT ".taf" -#define NO_METADATA -#define NO_COVER - -#include "treaty_builder.h" - -#include -#include -#include - -/* VB RNG constants */ -#define VB_RAND1 0x43FD43FD -#define VB_RAND2 0x00C39EC3 -#define VB_RAND3 0x00FFFFFF -#define VB_INIT 0x00A09E86 -static int32 vbr_state; - -/* - Unobfuscates one byte from a taf file. This should be called on each byte - in order, as the ADRIFT obfuscation function is stately. - - The de-obfuscation algorithm works by xoring the byte with the next - byte in the sequence produced by the Visual Basic pseudorandom number - generator, which is simulated here. -*/ -static unsigned char taf_translate (unsigned char c) -{ - int32 r; - - vbr_state = (vbr_state*VB_RAND1+VB_RAND2) & VB_RAND3; - r=UCHAR_MAX * (unsigned) vbr_state; - r/=((unsigned) VB_RAND3)+1; - return r^c; -} - -static int32 get_story_file_IFID(void *story_file, int32 extent, char *output, int32 output_extent) -{ - int adv; - unsigned char buf[4]; - unsigned char *sf=(unsigned char *)story_file; - vbr_state=VB_INIT; - - if (extent <12) return INVALID_STORY_FILE_RV; - - buf[3]=0; - /* Burn the first 8 bytes of translation */ - for(adv=0;adv<8;adv++) taf_translate(0); - /* Bytes 8-11 contain the Adrift version number in the formay N.NN */ - buf[0]=taf_translate(sf[8]); - taf_translate(0); - buf[1]=taf_translate(sf[10]); - buf[2]=taf_translate(sf[11]); - adv=atoi((char *) buf); - ASSERT_OUTPUT_SIZE(12); - sprintf(output,"ADRIFT-%03d-",adv); - return INCOMPLETE_REPLY_RV; - -} - -/* The claim algorithm for ADRIFT is to unobfuscate the first - seven bytes, and check for the word "Version". - It seems fairly unlikely that the obfuscated form of that - word would occur in the wild -*/ -static int32 claim_story_file(void *story_file, int32 extent) -{ - unsigned char buf[8]; - int i; - unsigned char *sf=(unsigned char *)story_file; - buf[7]=0; - vbr_state=VB_INIT; - if (extent<12) return INVALID_STORY_FILE_RV; - for(i=0;i<7;i++) buf[i]=taf_translate(sf[i]); - if (strcmp((char *)buf,"Version")) return INVALID_STORY_FILE_RV; - return VALID_STORY_FILE_RV; - -} diff --git a/babel/advsys.c b/babel/advsys.c deleted file mode 100644 index e0e1cf8..0000000 --- a/babel/advsys.c +++ /dev/null @@ -1,49 +0,0 @@ -/* advsys.c Treaty of Babel module for AdvSys files - * 2006 By L. Ross Raszewski - * - * This file depends on treaty_builder.h - * - * This file is public domain, but note that any changes to this file - * may render it noncompliant with the Treaty of Babel - */ - -#define FORMAT advsys -#define HOME_PAGE "http://www.ifarchive.org/if-archive/programming/advsys/" -#define FORMAT_EXT ".dat" -#define NO_METADATA -#define NO_COVER - -#include "treaty_builder.h" -#include -#include - -/* IFIDs for AdvSys are formed by prepending ADVSYS- to the default - MD5 ifid -*/ -static int32 get_story_file_IFID(void *story_file, int32 extent, char *output, int32 output_extent) -{ - /* This line suppresses a warning from the borland compiler */ - if (story_file || extent) { } - ASSERT_OUTPUT_SIZE(8); - strcpy(output,"ADVSYS-"); - return INCOMPLETE_REPLY_RV; - -} - -/* The Advsys claim algorithm: bytes 2-8 of the file contain the - text "ADVSYS", unobfuscated in the following way: - 30 is added to each byte, then the bits are reversed -*/ -static int32 claim_story_file(void *story_file, int32 extent) -{ - char buf[7]; - int i; - if (extent >=8) - { - for(i=0;i<6;i++) - buf[i]=~(((char *)story_file)[i+2]+30); - buf[6]=0; - if (strcmp(buf,"ADVSYS")==0) return VALID_STORY_FILE_RV; - } - return INVALID_STORY_FILE_RV; -} diff --git a/babel/agt.c b/babel/agt.c deleted file mode 100644 index 66b6575..0000000 --- a/babel/agt.c +++ /dev/null @@ -1,59 +0,0 @@ -/* agt.c Treaty of Babel module for AGX-encapsulated AGT files - * 2006 By L. Ross Raszewski - * - * This file depends on treaty_builder.h - * - * This file is public domain, but note that any changes to this file - * may render it noncompliant with the Treaty of Babel - */ - -#define FORMAT agt -#define HOME_PAGE "http://www.ifarchive.org/indexes/if-archiveXprogrammingXagt" -#define FORMAT_EXT ".agx" -#define NO_METADATA -#define NO_COVER - -#include "treaty_builder.h" -#include -#include - - -static char AGX_MAGIC[4] = { 0x58, 0xC7, 0xC1, 0x51 }; - -/* Helper functions to unencode integers from AGT source */ -static int32 read_agt_short(unsigned char *sf) -{ - return sf[0] | (int32) sf[1]<<8; -} -static int32 read_agt_int(unsigned char *sf) -{ - return (read_agt_short(sf+2) << 16) | read_agt_short(sf); - -} - -static int32 get_story_file_IFID(void *story_file, int32 extent, char *output, int32 output_extent) -{ - int32 l, game_version, game_sig; - unsigned char *sf=(unsigned char *)story_file; - - /* Read the position of the game desciption block */ - l=read_agt_int(sf+32); - if (extent -#include - -static int32 read_alan_int(unsigned char *from) -{ - return ((unsigned long int) from[3])| ((unsigned long int)from[2] << 8) | - ((unsigned long int) from[1]<<16)| ((unsigned long int)from[0] << 24); -} -static int32 get_story_file_IFID(void *story_file, int32 extent, char *output, int32 output_extent) -{ - - if (story_file || extent) { } - ASSERT_OUTPUT_SIZE(6); - strcpy(output,"ALAN-"); - return INCOMPLETE_REPLY_RV; -} -/* - The claim algorithm for Alan files is: - * For Alan 3, check for the magic word - * load the file length in blocks - * check that the file length is correct - * For alan 2, each word between byte address 24 and 81 is a - word address within the file, so check that they're all within - the file - * Locate the checksum and verify that it is correct -*/ -static int32 claim_story_file(void *story_file, int32 extent) -{ - unsigned char *sf = (unsigned char *) story_file; - int32 bf, i, crc=0; - if (extent < 160) return INVALID_STORY_FILE_RV; - if (memcmp(sf,"ALAN",4)) - { /* Identify Alan 2.x */ - bf=read_alan_int(sf+4); - if (bf > extent/4) return INVALID_STORY_FILE_RV; - for (i=24;i<81;i+=4) - if (read_alan_int(sf+i) > extent/4) return INVALID_STORY_FILE_RV; - for (i=160;i<(bf*4);i++) - crc+=sf[i]; - if (crc!=read_alan_int(sf+152)) return INVALID_STORY_FILE_RV; - return VALID_STORY_FILE_RV; - } - else - { /* Identify Alan 3 */ - bf=read_alan_int(sf+12); - if (bf > (extent/4)) return INVALID_STORY_FILE_RV; - for (i=184;i<(bf*4);i++) - crc+=sf[i]; - if (crc!=read_alan_int(sf+176)) return INVALID_STORY_FILE_RV; - - } - return INVALID_STORY_FILE_RV; -} diff --git a/babel/babel b/babel/babel deleted file mode 100644 index 1808ec1..0000000 Binary files a/babel/babel and /dev/null differ diff --git a/babel/babel-makefile b/babel/babel-makefile deleted file mode 100644 index 1b31887..0000000 --- a/babel/babel-makefile +++ /dev/null @@ -1,75 +0,0 @@ -# provisional makefile for babel -# -# Note that to compile babel, it is necessary only to compile all the .c -# files in this distribution and link them. -# -# This makefile is provided purely as a convenience. -# -# The following targets are available: -# babel: make babel -# babel.lib: make babel handler library (for Borland) -# ifiction.lib: make babel ifiction library (for Borland) -# babel.a: make babel handler library (for gcc) -# ifiction.a: make babel ifiction library (for gcc) -# dist: make babel.zip, the babel source distribution -# -# Note that this is a GNU makefile, and may not work with other makes -# -# Comment/uncomment the following lines to make the program work - -#CC=bcc32 -#OBJ=.obj -#BABEL_LIB=babel.lib -#IFICTION_LIB=ifiction.lib -#BABEL_FLIB=babel_functions.lib -#OUTPUT_BABEL= - -CC=gcc -g -OBJ=.o -BABEL_LIB=babel.a -BABEL_FLIB=babel_functions.a -IFICTION_LIB=ifiction.a -OUTPUT_BABEL=-o babel - -treaty_objs = zcode${OBJ} magscrolls${OBJ} blorb${OBJ} glulx${OBJ} hugo${OBJ} agt${OBJ} level9${OBJ} executable${OBJ} advsys${OBJ} tads${OBJ} tads2${OBJ} tads3${OBJ} adrift${OBJ} alan${OBJ} -bh_objs = babel_handler${OBJ} register${OBJ} misc${OBJ} md5${OBJ} ${treaty_objs} -ifiction_objs = ifiction${OBJ} register_ifiction${OBJ} -babel_functions = babel_story_functions${OBJ} babel_ifiction_functions${OBJ} babel_multi_functions${OBJ} -babel_objs = babel${OBJ} $(BABEL_FLIB) $(IFICTION_LIB) $(BABEL_LIB) - -babel: ${babel_objs} - ${CC} ${OUTPUT_BABEL} ${babel_objs} - -%${OBJ} : %.c - ${CC} -c $^ - -register${OBJ}: modules.h - -babel.lib: ${foreach dep,${bh_objs},${dep}.bl} - -ifiction.lib: ${foreach dep,${ifiction_objs},${dep}.il} - -babel_functions.lib: ${foreach dep,${babel_functions},${dep}.fl} - -%.obj.bl: %.obj - tlib babel.lib +-$^ - echo made > $@ - -%.obj.il: %.obj - tlib ifiction.lib +-$^ - echo made > $@ -%.obj.fl: %.obj - tlib babel_functions.lib +-$^ - echo made > $@ - -babel.a: $(bh_objs) - ar -r babel.a $^ - -ifiction.a: $(ifiction_objs) - ar -r ifiction.a $^ - -babel_functions.a: $(babel_functions) - ar -r babel_functions.a $^ - -dist: - cut -c0-31 MANIFEST | zip babel.zip -@ diff --git a/babel/babel.a b/babel/babel.a deleted file mode 100644 index 142fb78..0000000 Binary files a/babel/babel.a and /dev/null differ diff --git a/babel/babel.c b/babel/babel.c deleted file mode 100644 index 5bb7213..0000000 --- a/babel/babel.c +++ /dev/null @@ -1,248 +0,0 @@ -/* babel.c The babel command line program - * (c) 2006 By L. Ross Raszewski - * - * This code is freely usable for all purposes. - * - * This work is licensed under the Creative Commons Attribution2.5 License. - * To view a copy of this license, visit - * http://creativecommons.org/licenses/by/2.5/ or send a letter to - * Creative Commons, - * 543 Howard Street, 5th Floor, - * San Francisco, California, 94105, USA. - * - * This file depends upon misc.c and babel.h - * - * This file exports one variable: char *rv, which points to the file name - * for an ifiction file. This is used only by babel_ifiction_verify - */ - -#include "babel.h" -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif -int chdir(const char *); -char *getcwd(char *, int); -#ifdef __cplusplus -} -#endif - -char *fn; - -/* checked malloc function */ -void *my_malloc(int, char *); - -/* babel performs several fundamental operations, which are specified - by command-line objects. Each of these functions corresponds to - a story function (defined in babel_story_functions.c) or an - ifiction function (defined in babel_ifiction_functions.c) or both. - These are the types of those functions. -*/ - -typedef void (*story_function)(void); -typedef void (*ifiction_function)(char *); -typedef void (*multi_function)(char **, char *, int); -/* This structure tells babel what to do with its command line arguments. - if either of story or ifiction are NULL, babel considers this command line - option inappropriate for that type of file. -*/ -struct function_handler { - char *function; /* the textual command line option */ - story_function story; /* handler for story files */ - ifiction_function ifiction; /* handler for ifiction files */ - char *desc; /* Textual description for help text */ - }; - -struct multi_handler { - char *function; - char *argnames; - multi_function handler; - int nargsm; - int nargsx; - char *desc; - }; -/* This is an array of function_handler objects which specify the legal - arguments. It is terminated by a function_handler with a NULL function - */ -static struct function_handler functions[] = { - { "-ifid", babel_story_ifid, babel_ifiction_ifid, "Deduce IFID"}, - { "-format", babel_story_format, NULL, "Deduce story format" }, - { "-ifiction", babel_story_ifiction, NULL, "Extract iFiction file" }, - { "-meta", babel_story_meta, NULL, "Print story metadata" }, - { "-identify", babel_story_identify, NULL, "Describe story file" }, - { "-cover", babel_story_cover, NULL, "Extract cover art" }, - { "-story", babel_story_story, NULL, "Extract story file (ie. from a blorb)" }, - { "-verify", NULL, babel_ifiction_verify, "Verify integrity of iFiction file" }, - { "-lint", NULL, babel_ifiction_lint, "Verify style of iFiction file" }, - { "-fish", babel_story_fish, babel_ifiction_fish, "Extract all iFiction and cover art"}, - { "-unblorb", babel_story_unblorb, NULL, "As -fish, but also extract story files"}, - { NULL, NULL, NULL } - }; -static struct multi_handler multifuncs[] = { - { "-blorb", " []", babel_multi_blorb, 2, 3, "Bundle story file and (sparse) iFiction into blorb" }, - { "-blorbs", " []", babel_multi_blorb1, 2, 3, "Bundle story file and (sparse) iFiction into sensibly-named blorb" }, - { "-complete", " ", babel_multi_complete, 2, 2, "Create complete iFiction file from sparse iFiction" }, - { NULL, NULL, NULL, 0, 0, NULL } -}; - -int main(int argc, char **argv) -{ - char *todir="."; - char cwd[512]; - int ok=1,i, l, ll; - FILE *f; - char *md=NULL; - /* Set the input filename. Note that if this is invalid, babel should - abort before anyone notices - */ - fn=argv[2]; - - if (argc < 3) ok=0; - /* Detect the presence of the "-to " argument. - */ - if (ok && argc >=5 && strcmp(argv[argc-2], "-to")==0) - { - todir=argv[argc-1]; - argc-=2; - } - if (ok) for(i=0;multifuncs[i].function;i++) - if (strcmp(argv[1],multifuncs[i].function)==0 && - argc>= multifuncs[i].nargsm+2 && - argc <= multifuncs[i].nargsx+2) - { - - multifuncs[i].handler(argv+2, todir, argc-2); - exit(0); - } - - if (argc!=3) ok=0; - - /* Find the apropriate function_handler */ - if (ok) { - for(i=0;functions[i].function && strcmp(functions[i].function,argv[1]);i++); - if (!functions[i].function) ok=0; - else if (strcmp(fn,"-")) { - f=fopen(argv[2],"r"); - if (!f) ok=0; - } - } - - /* Print usage error if anything has gone wrong */ - if (!ok) - { - printf("%s: Treaty of Babel Analysis Tool (%s, %s)\n" - "Usage:\n", argv[0],BABEL_VERSION, TREATY_COMPLIANCE); - for(i=0;functions[i].function;i++) - { - if (functions[i].story) - printf(" babel %s \n",functions[i].function); - if (functions[i].ifiction) - printf(" babel %s \n",functions[i].function); - printf(" %s\n",functions[i].desc); - } - for(i=0;multifuncs[i].function;i++) - { - printf("babel %s %s\n %s\n", - multifuncs[i].function, - multifuncs[i].argnames, - multifuncs[i].desc); - } - - printf ("\nFor functions which extract files, add \"-to \" to the command\n" - "to set the output directory.\n" - "The input file can be specified as \"-\" to read from standard input\n" - "(This may only work for .iFiction files)\n"); - return 1; - } - - /* For story files, we end up reading the file in twice. This - is unfortunate, but unavoidable, since we want to be all - cross-platformy, so the first time we read it in, we - do the read in text mode, and the second time, we do it in binary - mode, and there are platforms where this makes a difference. - */ - ll=0; - if (strcmp(fn,"-")) - { - fseek(f,0,SEEK_END); - l=ftell(f)+1; - fseek(f,0,SEEK_SET); - md=(char *)my_malloc(l,"Input file buffer"); - fread(md,1,l-1,f); - md[l-1]=0; - } - else - while(!feof(stdin)) - { - char *tt, mdb[1024]; - int ii; - ii=fread(mdb,1,1024,stdin); - tt=(char *)my_malloc(ll+ii,"file buffer"); - if (md) { memcpy(tt,md,ll); free(md); } - memcpy(tt+ll,mdb,ii); - md=tt; - ll+=ii; - if (ii<1024) break; - } - - - if (strstr(md,""); - if (pp) *(pp+10)=0; - getcwd(cwd,512); - chdir(todir); - l=0; - if (functions[i].ifiction) - functions[i].ifiction(md); - else - fprintf(stderr,"Error: option %s is not valid for iFiction files\n", - argv[1]); - chdir(cwd); - } - - if (strcmp(fn,"-")) - { - free(md); - fclose(f); - } - if (l) - { /* Appears to be a story */ - char *lt; - if (functions[i].story) - { - if (strcmp(fn,"-")) lt=babel_init(argv[2]); - else { lt=babel_init_raw(md,ll); - free(md); - } - - if (lt) - { - getcwd(cwd,512); - chdir(todir); - if (!babel_get_authoritative() && strcmp(argv[1],"-format")) - printf("Warning: Story format could not be positively identified. Guessing %s\n",lt); - functions[i].story(); - - chdir(cwd); - } - else if (strcmp(argv[1],"-ifid")==0) /* IFID is calculable for all files */ - { - babel_md5_ifid(cwd,512); - printf("IFID: %s\n",cwd); - } - else - fprintf(stderr,"Error: Did not recognize format of story file\n"); - babel_release(); - } - else - fprintf(stderr,"Error: option %s is not valid for story files\n", - argv[1]); - } - - return 0; -} diff --git a/babel/babel.h b/babel/babel.h deleted file mode 100644 index 4108e3d..0000000 --- a/babel/babel.h +++ /dev/null @@ -1,56 +0,0 @@ -/* babel.h declarations for babel - * (c) 2006 By L. Ross Raszewski - * - * This code is freely usable for all purposes. - * - * This work is licensed under the Creative Commons Attribution2.5 License. - * To view a copy of this license, visit - * http://creativecommons.org/licenses/by/2.5/ or send a letter to - * Creative Commons, - * 543 Howard Street, 5th Floor, - * San Francisco, California, 94105, USA. - * - * This file depends upon treaty.h, babel_ifiction_functions.c, - * babel_story_functions.c, and babel_handler.c - * - */ - -#define BABEL_VERSION "0.2b" - -#include "treaty.h" -#include "babel_handler.h" -#include "ifiction.h" -/* Functions from babel_story_functions.c - * - * Each of these assumes that the story file has been loaded by babel_handler - * - * Each function babel_story_XXXX coresponds to the command line option -XXXX - */ -void babel_story_ifid(void); -void babel_story_cover(void); -void babel_story_ifiction(void); -void babel_story_meta(void); -void babel_story_fish(void); -void babel_story_format(void); -void babel_story_identify(void); -void babel_story_story(void); -void babel_story_unblorb(void); -/* Functions from babel_ifiction_functions.c - * - * as with babel_story_XXXX, but for metadata, which is handed in as the - * C string parameter - */ -void babel_ifiction_ifid(char *); -void babel_ifiction_verify(char *); -void babel_ifiction_fish(char *); -void babel_ifiction_lint(char *); - -/* Functions from babel_multi_functions.c - * - */ -void babel_multi_blorb(char **, char * , int); -void babel_multi_blorb1(char **, char * , int); -void babel_multi_complete(char **, char *, int); - -/* uncomment this line on platforms which limit extensions to 3 characters */ -/* #define THREE_LETTER_EXTENSIONS */ diff --git a/babel/babel_functions.a b/babel/babel_functions.a deleted file mode 100644 index ea8a1f6..0000000 Binary files a/babel/babel_functions.a and /dev/null differ diff --git a/babel/babel_handler.c b/babel/babel_handler.c deleted file mode 100644 index f7afb78..0000000 --- a/babel/babel_handler.c +++ /dev/null @@ -1,366 +0,0 @@ -/* babel_handler.c dispatches Treaty of Babel queries to the treaty modules - * (c) 2006 By L. Ross Raszewski - * - * This code is freely usable for all purposes. - * - * This work is licensed under the Creative Commons Attribution2.5 License. - * To view a copy of this license, visit - * http://creativecommons.org/licenses/by/2.5/ or send a letter to - * Creative Commons, - * 543 Howard Street, 5th Floor, - * San Francisco, California, 94105, USA. - * - * This file depends upon register.c, misc.c, babel.h, and treaty.h - * and L. Peter Deutsch's md5.c - * usage: - * char *babel_init(char *filename) - * Initializes babel to use the specified file. MUST be called before - * babel_treaty. Returns the human-readable name of the format - * or NULL if the format is not known. Do not call babel_treaty unless - * babel_init returned a nonzero value. - * The returned string will be the name of a babel format, possibly - * prefixed by "blorbed " to indicate that babel will process this file - * as a blorb. - * int32 babel_treaty(int32 selector, void *output, void *output_extent) - * Dispatches the call to the treaty handler for the currently loaded - * file. - * When processing a blorb, all treaty calls will be deflected to the - * special blorb handler. For the case of GET_STORY_FILE_IFID_SEL, - * The treaty handler for the underlying format will be called if an - * IFID is not found in the blorb resources. - * void babel_release() - * Frees all resources allocated during babel_init. - * You should do this even if babel_init returned NULL. - * After this is called, do not call babel_treaty until after - * another successful call to babel_init. - * char *babel_get_format() - * Returns the same value as the last call to babel_init (ie, the format name) - * int32 babel_md5_ifid(char *buffer, int extent); - * Generates an MD5 IFID from the loaded story. Returns zero if something - * went seriously wrong. - * - * If you wish to use babel in multiple threads, you must use the contextualized - * versions of the above functions. - * Each function above has a companion function whose name ends in _ctx (eg. - * "babel_treaty_ctx") which takes one additional argument. This argument is - * the babel context. A new context is returned by void *ctx=get_babel_ctx(), - * and should be released when finished by calling release_babel_ctx(ctx); - */ - - -#include "treaty.h" -#include -#include -#include -#include -#include "md5.h" - -void *my_malloc(int, char *); - -struct babel_handler -{ - TREATY treaty_handler; - TREATY treaty_backup; - void *story_file; - int32 story_file_extent; - void *story_file_blorbed; - int32 story_file_blorbed_extent; - char blorb_mode; - char *format_name; - char auth; -}; - -static struct babel_handler default_ctx; - -extern TREATY treaty_registry[]; -extern TREATY container_registry[]; - -static char *deeper_babel_init(char *story_name, void *bhp) -{ - struct babel_handler *bh=(struct babel_handler *) bhp; - int i; - char *ext; - - static char buffer[TREATY_MINIMUM_EXTENT]; - int best_candidate; - char buffert[TREATY_MINIMUM_EXTENT]; - - if (story_name) - { - ext=strrchr(story_name,'.'); - if (ext) for(i=0;ext[i];i++) ext[i]=tolower(ext[i]); - } - else ext=NULL; - best_candidate=-1; - if (ext) /* pass 1: try best candidates */ - for(i=0;container_registry[i];i++) - if (container_registry[i](GET_FILE_EXTENSIONS_SEL,NULL,0,buffer,TREATY_MINIMUM_EXTENT) >=0 && - strstr(buffer,ext) && - container_registry[i](CLAIM_STORY_FILE_SEL,bh->story_file,bh->story_file_extent,NULL,0)>=NO_REPLY_RV) - break; - if (!ext || !container_registry[i]) /* pass 2: try all candidates */ - { - - for(i=0;container_registry[i];i++) - {int l=container_registry[i](CLAIM_STORY_FILE_SEL,bh->story_file,bh->story_file_extent,NULL,0); - - if (l==VALID_STORY_FILE_RV) - break; - else if (l==NO_REPLY_RV && best_candidate < 0) best_candidate=i; - } -} - if (!container_registry[i] && best_candidate >=0) { bh->auth=0; i=best_candidate; } - if (container_registry[i]) - { - char buffer2[TREATY_MINIMUM_EXTENT]; - - bh->treaty_handler=container_registry[i]; - container_registry[i](GET_FORMAT_NAME_SEL,NULL,0,buffert,TREATY_MINIMUM_EXTENT); - bh->blorb_mode=1; - - bh->story_file_blorbed_extent=container_registry[i](CONTAINER_GET_STORY_EXTENT_SEL,bh->story_file,bh->story_file_extent,NULL,0); - if (bh->story_file_blorbed_extent>0) bh->story_file_blorbed=my_malloc(bh->story_file_blorbed_extent, "contained story file"); - if (bh->story_file_blorbed_extent<=0 || - container_registry[i](CONTAINER_GET_STORY_FORMAT_SEL,bh->story_file,bh->story_file_extent,buffer2,TREATY_MINIMUM_EXTENT)<0 || - container_registry[i](CONTAINER_GET_STORY_FILE_SEL,bh->story_file,bh->story_file_extent,bh->story_file_blorbed,bh->story_file_blorbed_extent)<=0 - ) - return NULL; - - for(i=0;treaty_registry[i];i++) - if (treaty_registry[i](GET_FORMAT_NAME_SEL,NULL,0,buffer,TREATY_MINIMUM_EXTENT)>=0 && - strcmp(buffer,buffer2)==0 && - treaty_registry[i](CLAIM_STORY_FILE_SEL,bh->story_file_blorbed,bh->story_file_blorbed_extent,NULL,0)>=NO_REPLY_RV) - break; - if (!treaty_registry[i]) - return NULL; - bh->treaty_backup=treaty_registry[i]; - sprintf(buffer,"%sed %s",buffert,buffer2); - return buffer; - } - - bh->blorb_mode=0; - best_candidate=-1; - - if (ext) /* pass 1: try best candidates */ - for(i=0;treaty_registry[i];i++) - if (treaty_registry[i](GET_FILE_EXTENSIONS_SEL,NULL,0,buffer,TREATY_MINIMUM_EXTENT) >=0 && - strstr(buffer,ext) && - treaty_registry[i](CLAIM_STORY_FILE_SEL,bh->story_file,bh->story_file_extent,NULL,0)>=NO_REPLY_RV) - break; - if (!ext || !treaty_registry[i]) /* pass 2: try all candidates */ - { - - for(i=0;treaty_registry[i];i++) - {int l; - l=treaty_registry[i](CLAIM_STORY_FILE_SEL,bh->story_file,bh->story_file_extent,NULL,0); - - if (l==VALID_STORY_FILE_RV) - break; - else if (l==NO_REPLY_RV && best_candidate < 0) best_candidate=i; - } - } - if (!treaty_registry[i]) - if (best_candidate>0) { i=best_candidate; bh->auth=0; } - else return NULL; - bh->treaty_handler=treaty_registry[i]; - - if (bh->treaty_handler(GET_FORMAT_NAME_SEL,NULL,0,buffer,TREATY_MINIMUM_EXTENT)>=0) - return buffer; - return NULL; - - -} - -static char *deep_babel_init(char *story_name, void *bhp) -{ - struct babel_handler *bh=(struct babel_handler *) bhp; - FILE *file; - - bh->treaty_handler=NULL; - bh->treaty_backup=NULL; - bh->story_file=NULL; - bh->story_file_extent=0; - bh->story_file_blorbed=NULL; - bh->story_file_blorbed_extent=0; - bh->format_name=NULL; - file=fopen(story_name, "rb"); - if (!file) return NULL; - fseek(file,0,SEEK_END); - bh->story_file_extent=ftell(file); - fseek(file,0,SEEK_SET); - bh->auth=1; - bh->story_file=my_malloc(bh->story_file_extent,"story file storage"); - fread(bh->story_file,1,bh->story_file_extent,file); - fclose(file); - - return deeper_babel_init(story_name, bhp); -} - -char *babel_init_ctx(char *sf, void *bhp) -{ - struct babel_handler *bh=(struct babel_handler *) bhp; - char *b; - b=deep_babel_init(sf,bh); - if (b) bh->format_name=strdup(b); - return b; -} -char *babel_init(char *sf) -{ - return babel_init_ctx(sf, &default_ctx); -} - -char *babel_init_raw_ctx(void *sf, int32 extent, void *bhp) -{ - struct babel_handler *bh=(struct babel_handler *) bhp; - char *b; - bh->treaty_handler=NULL; - bh->treaty_backup=NULL; - bh->story_file=NULL; - bh->story_file_extent=0; - bh->story_file_blorbed=NULL; - bh->story_file_blorbed_extent=0; - bh->format_name=NULL; - bh->story_file_extent=extent; - bh->auth=1; - bh->story_file=my_malloc(bh->story_file_extent,"story file storage"); - memcpy(bh->story_file,sf,extent); - - b=deeper_babel_init(NULL, bhp); - if (b) bh->format_name=strdup(b); - return b; -} -char *babel_init_raw(void *sf, int32 extent) -{ - return babel_init_raw_ctx(sf, extent, &default_ctx); -} - -void babel_release_ctx(void *bhp) -{ - struct babel_handler *bh=(struct babel_handler *) bhp; - if (bh->story_file) free(bh->story_file); - bh->story_file=NULL; - if (bh->story_file_blorbed) free(bh->story_file_blorbed); - bh->story_file_blorbed=NULL; - if (bh->format_name) free(bh->format_name); - bh->format_name=NULL; -} -void babel_release() -{ - babel_release_ctx(&default_ctx); -} -int32 babel_md5_ifid_ctx(char *buffer, int32 extent, void *bhp) -{ - struct babel_handler *bh=(struct babel_handler *) bhp; - md5_state_t md5; - int i; - unsigned char ob[16]; - if (extent <33 || bh->story_file==NULL) - return 0; - md5_init(&md5); - md5_append(&md5,bh->story_file,bh->story_file_extent); - md5_finish(&md5,ob); - for(i=0;i<16;i++) - sprintf(buffer+(2*i),"%02X",ob[i]); - buffer[32]=0; - return 1; - -} -int32 babel_md5_ifid(char *buffer, int32 extent) -{ - return babel_md5_ifid_ctx(buffer, extent, - &default_ctx); -} - -int32 babel_treaty_ctx(int32 sel, void *output, int32 output_extent,void *bhp) -{ - int32 rv; - struct babel_handler *bh=(struct babel_handler *) bhp; - if (!(sel & TREATY_SELECTOR_INPUT) && bh->blorb_mode) - rv=bh->treaty_backup(sel,bh->story_file_blorbed,bh->story_file_blorbed_extent,output, output_extent); - else - { - rv=bh->treaty_handler(sel,bh->story_file,bh->story_file_extent,output,output_extent); - if ((!rv|| rv==UNAVAILABLE_RV) && bh->blorb_mode) - rv=bh->treaty_backup(sel,bh->story_file_blorbed,bh->story_file_blorbed_extent,output, output_extent); - } - if (!rv && sel==GET_STORY_FILE_IFID_SEL) - return babel_md5_ifid_ctx(output,output_extent, bh); - if (rv==INCOMPLETE_REPLY_RV && sel==GET_STORY_FILE_IFID_SEL) - return babel_md5_ifid_ctx((void *)((char *) output+strlen((char *)output)), - output_extent-strlen((char *)output), - bh); - - return rv; -} -int32 babel_treaty(int32 sel, void *output, int32 output_extent) -{ - return babel_treaty_ctx(sel, output, output_extent, &default_ctx); -} -char *babel_get_format_ctx(void *bhp) -{ - struct babel_handler *bh=(struct babel_handler *) bhp; - return bh->format_name; -} -char *babel_get_format() -{ - return babel_get_format_ctx(&default_ctx); -} -void *get_babel_ctx() -{ - return my_malloc(sizeof(struct babel_handler), "babel handler context"); -} -void release_babel_ctx(void *b) -{ - free(b); -} - -int32 babel_get_length_ctx(void *bhp) -{ - struct babel_handler *bh=(struct babel_handler *) bhp; - return bh->story_file_extent; -} -int32 babel_get_length() -{ - return babel_get_length_ctx(&default_ctx); -} - -int32 babel_get_authoritative_ctx(void *bhp) -{ - struct babel_handler *bh=(struct babel_handler *) bhp; - return bh->auth; -} -int32 babel_get_authoritative() -{ - return babel_get_authoritative_ctx(&default_ctx); -} -void *babel_get_file_ctx(void *bhp) -{ - struct babel_handler *bh=(struct babel_handler *) bhp; - return bh->story_file; -} -void *babel_get_file() -{ - return babel_get_file_ctx(&default_ctx); -} - -int32 babel_get_story_length_ctx(void *ctx) -{ - struct babel_handler *bh=(struct babel_handler *) ctx; - if (bh->blorb_mode) return bh->story_file_blorbed_extent; - return bh->story_file_extent; -} -int32 babel_get_story_length() -{ - - return babel_get_story_length_ctx(&default_ctx); -} -void *babel_get_story_file_ctx(void *ctx) -{ - struct babel_handler *bh=(struct babel_handler *) ctx; - if (bh->blorb_mode) return bh->story_file_blorbed; - return bh->story_file; -} -void *babel_get_story_file() -{ - return babel_get_story_file_ctx(&default_ctx); -} diff --git a/babel/babel_handler.h b/babel/babel_handler.h deleted file mode 100644 index a01194a..0000000 --- a/babel/babel_handler.h +++ /dev/null @@ -1,65 +0,0 @@ -/* babel_handler.h declarations for the babel handler API - * (c) 2006 By L. Ross Raszewski - * - * This code is freely usable for all purposes. - * - * This work is licensed under the Creative Commons Attribution2.5 License. - * To view a copy of this license, visit - * http://creativecommons.org/licenses/by/2.5/ or send a letter to - * Creative Commons, - * 543 Howard Street, 5th Floor, - * San Francisco, California, 94105, USA. - * - */ - -#ifndef BABEL_HANDLER_H -#define BABEL_HANDLER_H - -#include "treaty.h" - -/* Functions from babel_handler.c */ -char *babel_init(char *filename); - /* initialize the babel handler */ -char *babel_init_raw(void *sf, int32 extent); - /* Initialize from loaded data */ -int32 babel_treaty(int32 selector, void *output, int32 output_extent); - /* Dispatch treaty calls */ -void babel_release(void); - /* Release babel_handler resources */ -char *babel_get_format(void); - /* return the format of the loaded file */ -int32 babel_md5_ifid(char *buffer, int32 extent); - /* IFID generator of last resort */ -int32 babel_get_length(void); - /* Fetch file length */ -int32 babel_get_story_length(void); - /* Fetch file length */ -int32 babel_get_authoritative(void); - /* Determine if babel handler has a good grasp on the format */ -void *babel_get_file(void); - /* Get loaded story file */ -void *babel_get_story_file(void); - /* Get loaded story file */ - -/* threadsafe versions of above */ -char *babel_init_ctx(char *filename, void *); - /* initialize the babel handler */ -int32 babel_treaty_ctx(int32 selector, void *output, int32 output_extent, void *); - /* Dispatch treaty calls */ -void babel_release_ctx(void *); - /* Release babel_handler resources */ -char *babel_get_format_ctx(void *); - /* return the format of the loaded file */ -int32 babel_md5_ifid_ctx(char *buffer, int extent, void *); - /* IFID generator of last resort */ -int32 babel_get_length_ctx(void *); -int32 babel_get_story_length_ctx(void *); -void *babel_get_file_ctx(void *bhp); -void *babel_get_story_ctx(void *bhp); -int32 babel_get_authoritative_ctx(void *bhp); -char *babel_init_raw_ctx(void *sf, int32 extent, void *bhp); -void *get_babel_ctx(void); -void release_babel_ctx(void *); - /* get and release babel contexts */ - -#endif diff --git a/babel/babel_ifiction_functions.c b/babel/babel_ifiction_functions.c deleted file mode 100644 index e59adf6..0000000 --- a/babel/babel_ifiction_functions.c +++ /dev/null @@ -1,168 +0,0 @@ -/* babel_ifiction_functions.c babel top-level operations for ifiction - * (c) 2006 By L. Ross Raszewski - * - * This code is freely usable for all purposes. - * - * This work is licensed under the Creative Commons Attribution2.5 License. - * To view a copy of this license, visit - * http://creativecommons.org/licenses/by/2.5/ or send a letter to - * Creative Commons, - * 543 Howard Street, 5th Floor, - * San Francisco, California, 94105, USA. - * - * This file depends upon babel.c (for rv), babel.h, misc.c and ifiction.c - */ - -#include "babel.h" -#include -#include -#include -#include - -#ifndef THREE_LETTER_EXTENSIONS -#define IFICTION_EXT ".iFiction" -#else -#define IFICTION_EXT ".ifi" -#endif - -void *my_malloc(int, char *); - -struct IFiction_Info -{ - char ifid[256]; - int wmode; -}; - -static void write_story_to_disk(struct XMLTag *xtg, void *ctx) -{ - char *b, *ep; - char *begin, *end; - char buffer[TREATY_MINIMUM_EXTENT]; - int32 l, j; - if (ctx) { } - - if (strcmp(xtg->tag,"story")==0) - { - begin=xtg->begin; - end=xtg->end; - l=end-begin+1; - b=(char *)my_malloc(l,"XML buffer"); - memcpy(b,begin,l-1); - b[l]=0; - j=ifiction_get_IFID(b,buffer,TREATY_MINIMUM_EXTENT); - if (!j) - { - fprintf(stderr,"No IFID found for this story\n"); - free(b); - return; - } - ep=strtok(buffer,","); - while(ep) - { - char buf2[256]; - FILE *f; - sprintf(buf2,"%s%s",ep,IFICTION_EXT); - f=fopen(buf2,"w"); - - if (!f || - fputs("\n" - "" - "\n" - " ", - f)==EOF || - fputs(b,f)==EOF || - fputs("/\n\n",f)==EOF - ) - { - fprintf(stderr,"Error writing to file %s\n",buf2); - } else - printf("Extracted %s\n",buf2); - if (f) fclose(f); - - ep=strtok(NULL,","); - } - - free(b); - } -} - -void babel_ifiction_ifid(char *md) -{ - char output[TREATY_MINIMUM_EXTENT]; - int i; - char *ep; - i=ifiction_get_IFID(md,output,TREATY_MINIMUM_EXTENT); - if (!i) - - { - fprintf(stderr,"Error: No IFIDs found in iFiction file\n"); - return; - } - ep=strtok(output,","); - while(ep) - { - printf("IFID: %s\n",ep); - ep=strtok(NULL,","); - } - -} - -static char isok; - -static void examine_tag(struct XMLTag *xtg, void *ctx) -{ - struct IFiction_Info *xti=(struct IFiction_Info *)ctx; - - if (strcmp("ifid",xtg->tag)==0 && strcmp(xti->ifid,"UNKNOWN")==0) - { - memcpy(xti->ifid,xtg->begin,xtg->end-xtg->begin); - xti->ifid[xtg->end-xtg->begin]=0; - } - -} -static void verify_eh(char *e, void *ctx) -{ - if (*((int *)ctx) < 0) return; - if (*((int *)ctx) || strncmp(e,"Warning",7)) - { isok=0; - fprintf(stderr, "%s\n",e); - } -} - - - -void babel_ifiction_fish(char *md) -{ - int i=-1; - ifiction_parse(md,write_story_to_disk,NULL,verify_eh,&i); -} - -void deep_ifiction_verify(char *md, int f) -{ - struct IFiction_Info ii; - int i=0; - ii.wmode=0; - isok=1; - strcpy(ii.ifid,"UNKNOWN"); - ifiction_parse(md,examine_tag,&ii,verify_eh,&i); - if (f&& isok) printf("Verified %s\n",ii.ifid); -} -void babel_ifiction_verify(char *md) -{ - deep_ifiction_verify(md,1); - -} - - -void babel_ifiction_lint(char *md) -{ - struct IFiction_Info ii; - int i=1; - ii.wmode=1; - isok=1; - strcpy(ii.ifid,"UNKNOWN"); - ifiction_parse(md,examine_tag,&ii,verify_eh,&i); - if (isok) printf("%s conforms to iFiction style guidelines\n",ii.ifid); -} - - diff --git a/babel/babel_multi_functions.c b/babel/babel_multi_functions.c deleted file mode 100644 index cd867c6..0000000 --- a/babel/babel_multi_functions.c +++ /dev/null @@ -1,312 +0,0 @@ -#include "babel.h" - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif -int chdir(const char *); -char *getcwd(char *, int); -#ifdef __cplusplus -} -#endif - -void deep_ifiction_verify(char *md, int f); -void * my_malloc(int32, char *); -char *blorb_chunk_for_name(char *name); -#ifndef THREE_LETTER_EXTENSIONS -static char *ext_table[] = { "zcode", ".zblorb", - "glulx", ".gblorb", - NULL, NULL - }; -#else -static char *ext_table[] = { "zcode", ".zlb", - "glulx", ".glb", - NULL, NULL - }; - -#endif -char *blorb_ext_for_name(char *fmt) -{ - int i; - for(i=0;ext_table[i];i+=2) - if (strcmp(ext_table[i],fmt)==0) return ext_table[i+1]; -#ifndef THREE_LETTER_EXTENSIONS - return ".blorb"; -#else - return ".blb"; -#endif -} - -char *deep_complete_ifiction(char *fn, char *ifid, char *format) -{ - FILE *f; - int32 i; - char *md; - char *id, *idp; - char *idb; - f=fopen(fn,"r"); - if (!f) { fprintf(stderr,"Error: Can not open file %s\n",fn); - return NULL; - } - fseek(f,0,SEEK_END); - i=ftell(f); - fseek(f,0,SEEK_SET); - md=(char *) my_malloc(i+1,"Metadata buffer"); - fread(md,1,i,f); - md[i]=0; - id=strstr(md,""); - if (id) *(id+10)=0; - fclose(f); - id=strdup(ifid); - idp=strtok(id,","); - /* Find the identification chunk */ - { - char *bp, *ep; - bp=strstr(md,""); - if (!bp) - { - idb=(char *)my_malloc(TREATY_MINIMUM_EXTENT+128,"ident buffer"); - sprintf(idb,"%s\n", format); - } - else - { - int ii; - ep=strstr(bp,""); - idb=(char *)my_malloc(TREATY_MINIMUM_EXTENT+128+(ep-bp),"ident buffer"); - for(ii=16;bp+ii"); - if (bp) - if (memcmp(bp+8,format,strlen(format))) - fprintf(stderr,"Error: Format in sparse .iFiction does not match story\n"); - - } - - } - /* Insert the new ifids */ - while(idp) - { - char bfr[TREATY_MINIMUM_EXTENT]; - sprintf(bfr,"%s",idp); - if (!strstr(idb,bfr)) { strcat(idb,bfr); strcat(idb,"\n"); } - idp=strtok(NULL,","); - - } - free(id); - idp=(char *) my_malloc(strlen(md)+strlen(idb)+64, "Output metadata"); -/* printf("%d bytes for metadata\n",strlen(md)+strlen(idb)+64);*/ - id=strstr(md,""); - id[0]=0; - id+=7; - strcpy(idp,md); - strcat(idp,"\n \n"); - strcat(idp,idb); - free(idb); - strcat(idp," \n"); - strcat(idp,id); - free(md); - md=idp; - deep_ifiction_verify(md, 0); - return md; -} - -void write_int(int32 i, FILE *f) -{ - char bf[4]; - bf[0]=(((unsigned) i) >> 24) & 0xFF; - bf[1]=(((unsigned) i) >> 16) & 0xFF; - bf[2]=(((unsigned) i) >> 8) & 0xFF; - bf[3]=(((unsigned) i)) & 0xFF; - fwrite(bf,1,4,f); -} -static void _babel_multi_blorb(char *outfile, char **args, char *todir , int argc) -{ - int32 total, storyl, coverl, i; - char buffer[TREATY_MINIMUM_EXTENT+10]; - char b2[TREATY_MINIMUM_EXTENT]; - - char cwd[512]; - char *cover, *md, *cvrf, *ep; - - FILE *f, *c; - if (argc!=2 && argc !=3) - { - fprintf(stderr,"Invalid usage\n"); - return; - } - if (!babel_init(args[0])) - { - fprintf(stderr,"Error: Could not determine the format of file %s\n",args[0]); - return; - } - if (babel_treaty(GET_STORY_FILE_IFID_SEL,buffer,TREATY_MINIMUM_EXTENT)<=0 || - babel_treaty(GET_FORMAT_NAME_SEL,b2,TREATY_MINIMUM_EXTENT)<0 - ) - { - fprintf(stderr,"Error: Could not deduce an IFID for file %s\n",args[0]); - return; - } - if (babel_get_length() != babel_get_story_length()) - { - fprintf(stderr,"Warning: Story file will be extacted from container before blorbing\n"); - } -/* printf("Completing ifiction\n");*/ - md=deep_complete_ifiction(args[1],buffer,b2); -/* printf("Ifiction is %d bytes long\n",strlen(md));*/ - ep=strchr(buffer,','); - if (ep) *ep=0; - if (outfile) - strcpy(buffer,outfile); - strcat(buffer,blorb_ext_for_name(b2)); - getcwd(cwd,512); - chdir(todir); - f=fopen(buffer,"wb"); - chdir(cwd); - if (!f) - { - fprintf(stderr,"Error: Error writing to file %s\n",buffer); - return; - } - storyl=babel_get_story_length(); - total=storyl + (storyl%2) + 36; - if (md) total+=8+strlen(md)+strlen(md)%2; - if (argc==3) - { - c=fopen(args[2],"rb"); - if (c) - { - fseek(c,0,SEEK_END); - coverl=ftell(c); - if (coverl > 5){ - - cover=(char *) my_malloc(coverl+2,"Cover art buffer"); - fseek(c,0,SEEK_SET); - fread(cover,1,coverl,c); - if (memcmp(cover+1,"PNG",3)==0) cvrf="PNG "; - else cvrf="JPEG"; - total += 32+coverl + (coverl%2); - } - else argc=2; - fclose(c); - } - else argc=2; - } -/* printf("Writing header\n;");*/ - fwrite("FORM",1,4,f); - write_int(total,f); -/* printf("Writing index\n;");*/ - fwrite("IFRSRIdx",1,8,f); - write_int(argc==3 ? 28:16,f); - write_int(argc==3 ? 2:1,f); -/* printf("Writing story\n;");*/ - fwrite("Exec", 1,4,f); - write_int(0,f); - write_int(argc==3 ? 48:36,f); - if (argc==3) - { -/* printf("Writing image\n;"); */ - fwrite("Pict", 1,4,f); - write_int(1,f); - write_int(56+storyl+(storyl%2),f); - } -/* printf("Invoking chunk for name %s\n",b2); */ - fwrite(blorb_chunk_for_name(b2),1,4,f); - write_int(storyl,f); -/* printf("Writing story data\n"); */ - fwrite(babel_get_story_file(),1,storyl,f); - if (storyl%2) fwrite("\0",1,1,f); - if (argc==3) - { -/* printf("Writing cover data header %s\n",cvrf); */ - fwrite(cvrf,1,4,f); -/* printf("Writing cover data size %d\n",coverl); */ - write_int(coverl,f); -/* printf("Writing cover data\n"); */ - fwrite(cover,1,coverl,f); - if (coverl%2) fwrite("\0",1,1,f); -/* printf("Done with cover\n");*/ -/* free(cover);*/ -/* printf("Writing frontispiece\n;");*/ - fwrite("Fspc\0\0\0\004\0\0\0\001",1,12,f); - } - - if (md) { -/* printf("Writing metadata\n;");*/ - fwrite("IFmd",1,4,f); - write_int(strlen(md),f); - fwrite(md,1,strlen(md),f); - if (strlen(md)%2) - fwrite("\0",1,1,f); - free(md); - } - - fclose(f); - printf("Created %s\n",buffer); - -} -void babel_multi_complete(char **args, char *todir, int argc) -{ - char buffer[TREATY_MINIMUM_EXTENT+10]; - char b2[TREATY_MINIMUM_EXTENT]; - char cwd[512]; - char *ep, *md; - FILE *f; - if (argc!=2) - { - fprintf(stderr,"Invalid usage\n"); - return; - } - if (!babel_init(args[0])) - { - fprintf(stderr,"Error: Could not determine the format of file %s\n",args[0]); - return; - } - if (babel_treaty(GET_STORY_FILE_IFID_SEL,buffer,TREATY_MINIMUM_EXTENT)<=0 - || babel_treaty(GET_FORMAT_NAME_SEL,b2,TREATY_MINIMUM_EXTENT)<0) - { - fprintf(stderr,"Error: Could not deduce an IFID for file %s\n",args[0]); - return; - } - md=deep_complete_ifiction(args[1],buffer, b2); - if (!md) return; - ep=strchr(buffer,','); - if (ep) *ep=0; - strcat(buffer,".iFiction"); - getcwd(cwd,512); - chdir(todir); - f=fopen(buffer,"w"); - chdir(cwd); - if (!f || !fputs(md,f)) - { - fprintf(stderr,"Error: Error writing to file %s\n",buffer); - return; - } - fclose(f); - free(md); - printf("Created %s\n",buffer); -} -void babel_multi_blorb(char **args, char *todir , int argc) -{ - _babel_multi_blorb(NULL,args,todir,argc); -} -void babel_multi_blorb1(char **args, char *todir , int argc) -{ - char *buf; - char *bb; - buf=(char *)my_malloc(strlen(args[0])+1,"blorb name buffer"); - strcpy(buf,args[0]); - bb=strrchr(buf,'.'); - if (bb) *bb=0; - _babel_multi_blorb(buf,args,todir,argc); - free(buf); - - -} diff --git a/babel/babel_story_functions.c b/babel/babel_story_functions.c deleted file mode 100644 index b1cf0e9..0000000 --- a/babel/babel_story_functions.c +++ /dev/null @@ -1,411 +0,0 @@ -/* babel_story_functions.c babel top-level operations for story files - * (c) 2006 By L. Ross Raszewski - * - * This code is freely usable for all purposes. - * - * This work is licensed under the Creative Commons Attribution2.5 License. - * To view a copy of this license, visit - * http://creativecommons.org/licenses/by/2.5/ or send a letter to - * Creative Commons, - * 543 Howard Street, 5th Floor, - * San Francisco, California, 94105, USA. - * - * This file depends upon babel_handler.c, babel.h, and misc.c - */ - -#include "babel.h" -#include -#include -#include - -#ifndef THREE_LETTER_EXTENSIONS -#define IFICTION_EXT ".iFiction" -#else -#define IFICTION_EXT ".ifi" -#endif -void *my_malloc(int32, char *); - -void babel_story_ifid() -{ - char buffer[TREATY_MINIMUM_EXTENT]; - char *ep; - int i; - i=babel_treaty(GET_STORY_FILE_IFID_SEL,buffer,TREATY_MINIMUM_EXTENT); - ep=strtok(buffer, ","); - while(ep) - { - printf("IFID: %s\n",ep); - ep=strtok(NULL,","); - } - if (!i) - fprintf(stderr,"Unable to create an IFID (A serious problem occurred while loading the file).\n"); - -} - - -void babel_story_format() -{ - char *b; - b=babel_get_format(); - if (!b) b="unknown"; - if (!babel_get_authoritative()) - printf("Format: %s (non-authoritative)\n",b); - else printf("Format: %s\n",b); -} - -static void deep_babel_ifiction(char stopped) -{ - char buffer[TREATY_MINIMUM_EXTENT]; - char *md; - char *ep; - int32 i; - FILE *f; - - if (stopped!=2) - { - i=babel_treaty(GET_STORY_FILE_IFID_SEL,buffer,TREATY_MINIMUM_EXTENT); - if (i==0 && !babel_md5_ifid(buffer, TREATY_MINIMUM_EXTENT)) - { - fprintf(stderr,"Unable to create an IFID (A serious problem occurred while loading the file).\n"); - return; - } - - - ep=strtok(buffer, ","); - } - else ep="-"; - i=babel_treaty(GET_STORY_FILE_METADATA_EXTENT_SEL,NULL,0); - if (i<=0) - { - if (stopped) printf("No iFiction record for %s\n",buffer); - return; - } - md=(char *)my_malloc(i,"Metadata buffer"); - if (babel_treaty(GET_STORY_FILE_METADATA_SEL,md,i)<0) - { - fprintf(stderr,"A serious error occurred while retrieving metadata.\n"); - free(md); - return; - } - while(ep) - { - char epb[TREATY_MINIMUM_EXTENT+9]; - if (stopped!=2) - { - strcpy(epb,ep); - strcat(epb, IFICTION_EXT); - - f=fopen(epb,"w"); - } - else f=stdout; - - if (!f || fputs(md,f)==EOF) - fprintf(stderr,"A serious error occurred writing to disk.\n"); - else if (stopped!=2) printf("Extracted %s\n",epb); - if (f) fclose(f); - if (stopped) break; - ep=strtok(NULL,","); - } - free(md); -} - -void babel_story_ifiction() -{ - deep_babel_ifiction(1); -} -static char *get_jpeg_dim(void *img, int32 extent) -{ - unsigned char *dp=(unsigned char *) img; - unsigned char *ep=dp+extent; - static char buffer[256]; - unsigned int t1, t2, w, h; - - - t1=*(dp++); - t2=*(dp++); - if (t1!=0xff || t2!=0xD8 ) - { - return "(invalid)"; - } - - while(1) - { - if (dp>ep) return "(invalid)"; - for(t1=*(dp++);t1!=0xff;t1=*(dp++)) if (dp>ep) return "(invalid)"; - do { t1=*(dp++); if (dp>ep) return "(invalid 4)";} while (t1 == 0xff); - - if ((t1 & 0xF0) == 0xC0 && !(t1==0xC4 || t1==0xC8 || t1==0xCC)) - { - dp+=3; - if (dp>ep) return "(invalid)"; - h=*(dp++) << 8; - if (dp>ep) return "(invalid)"; - h|=*(dp++); - if (dp>ep) return "(invalid)"; - w=*(dp++) << 8; - if (dp>ep) return "(invalid)"; - w|=*(dp); - sprintf(buffer, "(%dx%d)",w,h); - return buffer; - } - else if (t1==0xD8 || t1==0xD9) - break; - else - { int l; - - if (dp>ep) return "(invalid)"; - l=*(dp++) << 8; - if (dp>ep) return "(invalid)"; - l|= *(dp++); - l-=2; - dp+=l; - if (dp>ep) return "(invalid)"; - } - } - return "(invalid)"; -} - -static int32 read_int(unsigned char *mem) -{ - int32 i4 = mem[0], - i3 = mem[1], - i2 = mem[2], - i1 = mem[3]; - return i1 | (i2<<8) | (i3<<16) | (i4<<24); -} - - -static char *get_png_dim(void *img, int32 extent) -{ - unsigned char *dp=(unsigned char *)img; - static char buffer[256]; - int32 w, h; - if (extent<33 || - !(dp[0]==137 && dp[1]==80 && dp[2]==78 && dp[3]==71 && - dp[4]==13 && dp[5] == 10 && dp[6] == 26 && dp[7]==10)|| - !(dp[12]=='I' && dp[13]=='H' && dp[14]=='D' && dp[15]=='R')) - return "(invalid)"; - w=read_int(dp+16); - h=read_int(dp+20); - sprintf(buffer,"(%dx%d)",w,h); - return buffer; -} -static char *get_image_dim(void *img, int32 extent, int fmt) -{ - if (fmt==JPEG_COVER_FORMAT) return get_jpeg_dim(img,extent); - else if (fmt==PNG_COVER_FORMAT) return get_png_dim(img, extent); - return "(unknown)"; - -} -static void deep_babel_cover(char stopped) -{ - char buffer[TREATY_MINIMUM_EXTENT]; - void *md; - char *ep; - char *ext; - char *dim; - int32 i,j; - FILE *f; - i=babel_treaty(GET_STORY_FILE_IFID_SEL,buffer,TREATY_MINIMUM_EXTENT); - if (i==0) - if (babel_md5_ifid(buffer, TREATY_MINIMUM_EXTENT)) - printf("IFID: %s\n",buffer); - else - { - fprintf(stderr,"Unable to create an IFID (A serious problem occurred while loading the file).\n"); - return; - } - else - - ep=strtok(buffer, ","); - i=babel_treaty(GET_STORY_FILE_COVER_EXTENT_SEL,NULL,0); - j=babel_treaty(GET_STORY_FILE_COVER_FORMAT_SEL,NULL,0); - - if (i<=0 || j<=0) - { - if (stopped) printf("No cover art for %s\n",buffer); - return; - } - if (j==PNG_COVER_FORMAT) ext=".png"; - else if (j==JPEG_COVER_FORMAT) ext=".jpg"; - md=my_malloc(i,"Image buffer"); - if (babel_treaty(GET_STORY_FILE_COVER_SEL,md,i)<0) - { - fprintf(stderr,"A serious error occurred while retrieving cover art.\n"); - free(md); - return; - } - dim=get_image_dim(md,i,j); - while(ep) - { - char epb[TREATY_MINIMUM_EXTENT+9]; - strcpy(epb,ep); - strcat(epb, ext); - - f=fopen(epb,"wb"); - if (!f || fwrite(md,1,i,f)==EOF) - fprintf(stderr,"A serious error occurred writing to disk.\n"); - else printf("Extracted %s %s\n",epb, dim); - if (f) fclose(f); - if (stopped) break; - ep=strtok(NULL,","); - } - free(md); -} - -void babel_story_cover() -{ - deep_babel_cover(1); -} - -void babel_story_fish() -{ - deep_babel_ifiction(0); - deep_babel_cover(0); -} - -static char *get_biblio(void) -{ - int32 i; - char *md; - char *bib="No bibliographic data"; - char *bibb; char *bibe; - char *t; - static char buffer[TREATY_MINIMUM_EXTENT]; - - i=babel_treaty(GET_STORY_FILE_METADATA_EXTENT_SEL,NULL,0); - if (i<=0) return bib; - - md=(char *) my_malloc(i,"Metadata buffer"); - if (babel_treaty(GET_STORY_FILE_METADATA_SEL,md,i)<0) return bib; - - bibb=strstr(md,""); - if (!bibb) { free(md); return bib; } - bibe=strstr(bibb,""); - if (bibe) *bibe=0; - t=strstr(bibb,""); - if (t) - { - t+=7; - bibe=strstr(t,""); - if (bibe) - { - *bibe=0; - bib=buffer; - for(i=0;t[i];i++) if (t[i]<0x20 || t[i]>0x7e) t[i]='_'; - sprintf(buffer, "\"%s\" ",t); - *bibe='<'; - } - else strcpy(buffer," "); - } - t=strstr(bibb,""); - if (t) - { - t+=8; - bibe=strstr(t,""); - if (bibe) - { - bib=buffer; - *bibe=0; - for(i=0;t[i];i++) if (t[i]<0x20 || t[i]>0x7e) t[i]='_'; - strcat(buffer, "by "); - strcat(buffer, t); - *bibe='<'; - } - else strcat(buffer, ""); - } - free(md); - return bib; - -} -void babel_story_identify() -{ - int32 i, j, l; - char *b, *cf, *dim; - char buffer[TREATY_MINIMUM_EXTENT]; - - printf("%s\n",get_biblio()); - babel_story_ifid(); - b=babel_get_format(); - if (!b) b="unknown"; - l=babel_get_length() / 1024; - - - i=babel_treaty(GET_STORY_FILE_COVER_EXTENT_SEL,NULL,0); - j=babel_treaty(GET_STORY_FILE_COVER_FORMAT_SEL,NULL,0); - - if (i<=0 || j<=0) - { - cf="no cover"; - } - else - { - char *md=my_malloc(i,"Image buffer"); - if (babel_treaty(GET_STORY_FILE_COVER_SEL,md,i)<0) - { - cf="no cover"; - } - else - { - dim=get_image_dim(md,i,j)+1; - dim[strlen(dim)-1]=0; - if (j==JPEG_COVER_FORMAT) cf="jpeg"; - else if (j==PNG_COVER_FORMAT) cf="png"; - else cf="unknown format"; - sprintf(buffer,"cover %s %s",dim,cf); - cf=buffer; - } - } - printf("%s, %dk, %s\n",b, l,cf); -} - -void babel_story_meta() -{ - deep_babel_ifiction(2); -} - -void babel_story_story() -{ - int32 j,i; - void *p; - FILE *f; - char *ep; - char buffer[TREATY_MINIMUM_EXTENT+20]; - j=babel_get_story_length(); - p=babel_get_story_file(); - if (!j || !p) - { - fprintf(stderr,"A serious error occurred while retrieving the story file.\n"); - return; - } - - i=babel_treaty(GET_STORY_FILE_IFID_SEL,buffer,TREATY_MINIMUM_EXTENT); - if (i==0 && !babel_md5_ifid(buffer, TREATY_MINIMUM_EXTENT)) - { - fprintf(stderr,"Unable to create an IFID (A serious problem occurred while loading the file).\n"); - return; - } - ep=strchr(buffer, ','); - if (!ep) ep=buffer+strlen(buffer); - *ep=0; - babel_treaty(GET_STORY_FILE_EXTENSION_SEL,ep,19); - f=fopen(buffer,"wb"); - if (!f || !fwrite(p,1,j,f)) - { - fprintf(stderr,"A serious error occurred writing to disk.\n"); - return; - } - fclose(f); - printf("Extracted %s\n",buffer); - - - -} - -void babel_story_unblorb() -{ - deep_babel_ifiction(1); - deep_babel_cover(1); - babel_story_story(); - -} diff --git a/babel/blorb.c b/babel/blorb.c deleted file mode 100644 index ebb84e4..0000000 --- a/babel/blorb.c +++ /dev/null @@ -1,245 +0,0 @@ -/* blorb.c Babel interface to blorb files - * Copyright 2006 by L. Ross Raszewski - * - * This code is freely usable for all purposes. - * - * This work is licensed under the Creative Commons Attribution2.5 License. - * To view a copy of this license, visit - * http://creativecommons.org/licenses/by/2.5/ or send a letter to - * Creative Commons, - * 543 Howard Street, 5th Floor, - * San Francisco, California, 94105, USA. - * - * This file depends upon treaty_builder.h, misc.c and ifiction.c - * - * Header note: to add support for new executable chunk types, see - * TranslateExec. - * - * This file defines a Treaty of Babel compatable module for handling blorb - * files. However, blorb files are not themselves a babel format. This module - * is used internally by the babel program to handle blorbs. - * - * As a result, if GET_STORY_FILE_IFID_SEL returns NO_REPLY_RV, - * you should check the story file against the babel registry before resorting - * to the default IFID calculation. - * - */ -#define FORMAT blorb -#define HOME_PAGE "http://eblong.com/zarf/blorb" -#define FORMAT_EXT ".blorb,.blb,.zblorb,.zlb,.gblorb,.glb" -#define CONTAINER_FORMAT -#include "treaty_builder.h" -#include -#include - -extern TREATY treaty_registry[]; -/* The following is the translation table of Blorb chunk types to - babel formats. it is NULL-terminated. */ -static char *TranslateExec[] = { "ZCOD", "zcode", - "GLUL", "glulx", - "TAD2", "tads2", - "TAD3", "tads3", - NULL, NULL }; - -void *my_malloc(int32, char *); -int32 ifiction_get_IFID(char *, char *, int32); - -static int32 read_int(void *inp) -{ - unsigned char *mem=(unsigned char *)inp; - int32 i4 = mem[0], - i3 = mem[1], - i2 = mem[2], - i1 = mem[3]; - return i1 | (i2<<8) | (i3<<16) | (i4<<24); -} - - -static int32 blorb_get_chunk(void *blorb_file, int32 extent, char *id, int32 *begin, int32 *output_extent) -{ - int32 i=12, j; - while(i extent) return NO_REPLY_RV; - *begin=i+8; - return 1; - } - - j=read_int((char *)blorb_file+i+4); - if (j%2) j++; - i+=j+8; - - } - return NO_REPLY_RV; -} -static int32 blorb_get_resource(void *blorb_file, int32 extent, char *rid, int32 number, int32 *begin, int32 *output_extent) -{ - int32 ridx_len; - int32 i,j; - void *ridx; - if (blorb_get_chunk(blorb_file, extent,"RIdx",&i,&ridx_len)==NO_REPLY_RV) - return NO_REPLY_RV; - - ridx=(char *)blorb_file+i+4; - ridx_len=read_int((char *)blorb_file+i); - for(i=0;i -#include - -static char elfmagic[] = { 0x7f, 0x45, 0x4c, 0x46, 0 }; -static char javamagic[] = { 0xCA, 0xFE, 0xBA, 0xBE, 0 }; -static char amigamagic[] = { 0, 0, 3, 0xe7, 0 }; -static char machomagic[] = { 0xFE, 0xED, 0xFA, 0xCE, 0}; -struct exetype -{ - char *magic; - char *name; - int len; -}; -static struct exetype magic[]= { { "MZ", "MZ", 2 }, - { elfmagic, "ELF", 4 }, - { javamagic, "JAVA", 4 }, - { amigamagic, "AMIGA", 4 }, - { "#! ", "SCRIPT", 3 }, - { machomagic, "MACHO",4 }, - { "APPL", "MAC",4 }, - { NULL, NULL, 0 } }; - -static char *deduce_magic(void *sf, int32 extent) -{ - int i; - for(i=0;magic[i].magic;i++) - if (extent >= magic[i].len && memcmp(magic[i].magic,sf,magic[i].len)==0) - return magic[i].name; - return NULL; -} - -static int32 claim_story_file(void *sf, int32 extent) -{ - if (deduce_magic(sf,extent)) return VALID_STORY_FILE_RV; - return NO_REPLY_RV; -} -static int32 get_story_file_IFID(void *sf, int32 extent, char *output, int32 output_extent) -{ - char *o; - o=deduce_magic(sf,extent); - if (!o) return 0; - ASSERT_OUTPUT_SIZE((signed) strlen(o)+2); - strcpy(output,o); - strcat(output,"-"); - return INCOMPLETE_REPLY_RV; -} diff --git a/babel/glulx.c b/babel/glulx.c deleted file mode 100644 index ea1b3c4..0000000 --- a/babel/glulx.c +++ /dev/null @@ -1,81 +0,0 @@ -/* glulx.c Treaty of Babel module for Glulx files - * 2006 By L. Ross Raszewski - * - * This file depends on treaty_builder.h - * - * This file is public domain, but note that any changes to this file - * may render it noncompliant with the Treaty of Babel - */ - -#define FORMAT glulx -#define HOME_PAGE "http://eblong.com/zarf/glulx" -#define FORMAT_EXT ".ulx" -#define NO_METADATA -#define NO_COVER - -#include "treaty_builder.h" -#include -#include - -static int32 read_int(unsigned char *mem) -{ - int32 i4 = mem[0], - i3 = mem[1], - i2 = mem[2], - i1 = mem[3]; - return i1 | (i2<<8) | (i3<<16) | (i4<<24); -} - - - -static int32 get_story_file_IFID(void *story_file, int32 extent, char *output, int32 output_extent) -{ - int32 i,j, k; - char ser[7]; - char buffer[32]; - - - if (extent<256) return INVALID_STORY_FILE_RV; - for(i=0;i -#include - -static int32 get_story_file_IFID(void *s_file, int32 extent, char *output, int32 output_extent) -{ - - int32 i,j; - char ser[9]; - char buffer[32]; - char *story_file = (char *) s_file; - - - if (extent<0x0B) return INVALID_STORY_FILE_RV; - - for(i=0;i0x7e) return INVALID_STORY_FILE_RV; - for(i=0x0b;i<0x18;i+=2) - if (read_hugo_addx(sf+i) * scale > extent) return INVALID_STORY_FILE_RV; - - return VALID_STORY_FILE_RV; -} diff --git a/babel/ifiction.a b/babel/ifiction.a deleted file mode 100644 index 6dda84f..0000000 Binary files a/babel/ifiction.a and /dev/null differ diff --git a/babel/ifiction.c b/babel/ifiction.c deleted file mode 100644 index cb620e7..0000000 --- a/babel/ifiction.c +++ /dev/null @@ -1,534 +0,0 @@ -/* ifiction.c common babel interface for processing ifiction metadata - * (c) 2006 By L. Ross Raszewski - * - * This code is freely usable for all purposes. - * - * This work is licensed under the Creative Commons Attribution2.5 License. - * To view a copy of this license, visit - * http://creativecommons.org/licenses/by/2.5/ or send a letter to - * Creative Commons, - * 543 Howard Street, 5th Floor, - * San Francisco, California, 94105, USA. - * - * This file depends on treaty.h - * - * This file contains common routines for handling ifiction metadata strings - * - * int32 ifiction_get_IFID(char *metadata, char *output, int32 output_extent) - * does what the babel treaty function GET_STORY_FILE_IFID_SEL would do for ifiction - * - * void ifiction_parse(char *md, IFCloseTag close_tag, void *close_ctx, - * IFErrorHandler error_handler, void *error_ctx) - * parses the given iFiction metadata. close_tag(struct XMLtag xtg, close_ctx) - * is called for each tag as it is closed, error_handler(char *error, error_ctx) - * is called each time a structural or logical error is found in the iFiction - * This is a very simple XML parser, and probably not as good as any "real" - * XML parser. Its only two benefits are that (1) it's really small, and (2) - * it strictly checks the ifiction record against the Treaty of Babel - * requirements - * - */ - -#include "ifiction.h" -#include -#include -#include -#include - -void *my_malloc(int, char *); -extern char *format_registry[]; - - -static int32 llp; -static char *lnlst; - -static char utfeol[3] = { 0xe2, 0x80, 0xa8 }; -static int32 getln(char *endp) -{ - for(;lnlst"); - if (!ifid_begin) return NO_REPLY_RV; - ifid_begin+=6; - - ifid_end=strstr(ifid_begin,""); - if (!ifid_end) return NO_REPLY_RV; - if (output_extent<=(ifid_end-ifid_begin)) return INVALID_USAGE_RV; - - memcpy(output,ifid_begin,ifid_end-ifid_begin); - - output[ifid_end-ifid_begin]=0; - - return ifid_end-metadata+7; -} - - -int32 ifiction_get_IFID(char *metadata, char *output, int32 output_extent) -{ - int32 j=0, k; - - while(*metadata) - { - if ((k=ifiction_get_first_IFID(metadata,output,output_extent)) <= 0) break; - j++; - metadata+=k; - output_extent-=strlen(output)+1; - output+=strlen(output); - *output=','; - output++; - } - if (*(output-1)==',') *(output-1)=0; - return j; -} - - -static char *leaf_tags[] = { "ifid", - "format", - "bafn", - "title", - "author", - "headline", - "firstpublished", - "genre", - "group", - "description", - "leafname", - "url", - "authoremail", - "height", - "width", - - NULL - }; -static char *one_per[] = { "identification", - "bibliographic", - "format", - "title", - "author", - "headline", - "firstpublished", - "genre", - "group", - "description", - "leafname", - "height", - "width", - "forgiveness", - "colophon", - NULL - }; - -static char *required[] = { - "cover", "height", - "cover", "width", - "cover", "format", - "resources", "auxiliary", - "auxiliary", "leafname", - "auxiliary", "description", - "ifiction", "story", - "story", "identification", - "story", "bibliographic", - "identification", "ifid", - "identification", "format", - "bibliographic", "title", - "bibliographic", "author", - "colophon", "generator", - "colophon", "originated", - NULL, NULL - }; -static char *zarfian[] = { - "Merciful", - "Polite", - "Tough", - "Nasty", - "Cruel", - NULL - }; - -struct ifiction_info { - int32 width; - int32 height; - int format; - }; -static void ifiction_validate_tag(struct XMLTag *xtg, struct ifiction_info *xti, IFErrorHandler err_h, void *ectx) -{ - int i; - char ebuf[512]; - struct XMLTag *parent=xtg->next; - if (parent) - { - for(i=0;leaf_tags[i];i++) - if (strcmp(parent->tag,leaf_tags[i])==0) - { - sprintf(ebuf, "Error: (line %d) Tag <%s> is not permitted within tag <%s>", - xtg->beginl,xtg->tag,parent->tag); - err_h(ebuf,ectx); - } - for(i=0;required[i];i+=2) - if (strcmp(required[i],parent->tag)==0 && strcmp(required[i+1],xtg->tag)==0) - parent->rocurrences[i]=1; - for(i=0;one_per[i];i++) - if (strcmp(one_per[i],xtg->tag)==0) - if (parent->occurences[i]) { - sprintf(ebuf,"Error: (line %d) Found more than one <%s> within <%s>",xtg->beginl,xtg->tag, - parent->tag); - err_h(ebuf,ectx); - } - else parent->occurences[i]=1; - } - for(i=0;required[i];i+=2) - if (strcmp(required[i],xtg->tag)==0 && !xtg->rocurrences[i]) - { - sprintf(ebuf,"Error: (line %d) Tag <%s> is required within <%s>",xtg->beginl, required[i+1],xtg->tag); - err_h(ebuf,ectx); - } - if (parent && strcmp(parent->tag,"identification")==0) - { - if (strcmp(xtg->tag,"format")==0) - { - int i; - for(i=0;format_registry[i];i++) if (memcmp(xtg->begin,format_registry[i],strlen(format_registry[i]))==0) break; - if (format_registry[i]) xti->format=i; - else - { - char bf[256]; - memcpy(bf,xtg->begin,xtg->end-xtg->begin); - bf[xtg->end-xtg->begin]=0; - xti->format=-1; - sprintf(ebuf,"Warning: (line %d) Unknown format %s.",xtg->beginl,bf); - err_h(ebuf,ectx); - } - } - } - if (parent && strcmp(parent->tag,"cover")==0) - { - if (strcmp(xtg->tag,"width")==0) - { - int i; - sscanf(xtg->begin,"%d",&i); - if (i<120) - { - sprintf(ebuf,"Warning: (line %d) Cover art width should not be less than 120.",xtg->beginl); - err_h(ebuf,ectx); - } - if (i>1200) - { - sprintf(ebuf,"Warning: (line %d) Cover art width should not exceed 1200.",xtg->beginl); - err_h(ebuf,ectx); - } - if (!xti->width) xti->width=i; - if (xti->height && (xti->width> 2 * xti->height || xti->height > 2 * xti->width)) - { - sprintf(ebuf,"Warning: (line %d) Cover art aspect ratio exceeds 2:1.",xtg->beginl); - err_h(ebuf,ectx); - } - - } - if (strcmp(xtg->tag,"height")==0) - { - int i; - sscanf(xtg->begin,"%d",&i); - if (i<120) - { - sprintf(ebuf,"Warning: (line %d) Cover art height should not be less than 120.",xtg->beginl); - err_h(ebuf,ectx); - } - if (i>1200) - { - sprintf(ebuf,"Warning: (line %d) Cover art height should not exceed 1200.",xtg->beginl); - err_h(ebuf,ectx); - } - if (!xti->height) xti->height=i; - if (xti->width && (xti->width> 2 * xti->height || xti->height > 2 * xti->width)) - { - sprintf(ebuf,"Warning: (line %d) Cover art aspect ratio exceeds 2:1.",xtg->beginl); - err_h(ebuf,ectx); - } - - } - if (strcmp(xtg->tag,"format")==0 && memcmp(xtg->begin,"jpg",3) && memcmp(xtg->begin,"png",3)) - { - sprintf(ebuf,"Warning: (line %d) should be one of: png, jpg.",xtg->beginl); - err_h(ebuf,ectx); - } - } - if (parent && strcmp(parent->tag,"bibliographic")==0) - { - char *p; - if (isspace(*xtg->begin)|| isspace(*(xtg->end-1))) - { - sprintf(ebuf,"Warning: (line %d) Extraneous spaces at beginning or end of tag <%s>.",xtg->beginl,xtg->tag); - err_h(ebuf,ectx); - } - for(p=xtg->begin;pend-1;p++) -/* Obsoleted by Revision 6 - if (isspace(*p) && isspace(*(p+1))) - { - sprintf(ebuf,"Warning: (line %d) Extraneous spaces found in tag <%s>.",xtg->beginl, xtg->tag); - err_h(ebuf,ectx); - } - else if (isspace(*p) && *p!=' ') - { - sprintf(ebuf,"Warning: (line %d) Improper whitespace character found in tag <%s>.",xtg->beginl, xtg->tag); - err_h(ebuf,ectx); - - } -*/ - if (strcmp(xtg->tag, "description") && xtg->end-xtg->begin > 240) - { - sprintf(ebuf,"Warning: (line %d) Tag <%s> length exceeds treaty guidelines",xtg->beginl, xtg->tag); - err_h(ebuf,ectx); - } - if (strcmp(xtg->tag, "description")==0 && xtg->end-xtg->begin > 2400) - { - sprintf(ebuf,"Warning: (line %d) Tag <%s> length exceeds treaty guidelines",xtg->beginl, xtg->tag); - err_h(ebuf,ectx); - } - if (strcmp(xtg->tag,"firstpublished")==0) - { - int l=xtg->end-xtg->begin; - if ((l!=4 && l!=10) || - (!isdigit(xtg->begin[0]) || - !isdigit(xtg->begin[1]) || - !isdigit(xtg->begin[2]) || - !isdigit(xtg->begin[3])) || - (l==10 && ( xtg->begin[4]!='-' || - xtg->begin[7]!='-' || - !isdigit(xtg->begin[5]) || - !isdigit(xtg->begin[6]) || - !(xtg->begin[5]=='0' || xtg->begin[5]=='1') || - !(xtg->begin[5]=='0' || xtg->begin[6]<='2') || - !isdigit(xtg->begin[8]) || - !isdigit(xtg->begin[9])))) - { - sprintf(ebuf,"Warning: (line %d) Tag <%s> should be format YYYY or YYYY-MM-DD",xtg->beginl, xtg->tag); - err_h(ebuf,ectx); - } - } - if (strcmp(xtg->tag,"seriesnumber")==0) - { - char *l; - if (*xtg->begin=='0' && xtg->end!=xtg->begin+1) - { - sprintf(ebuf,"Warning: (line %d) Tag <%s> should not use leading zeroes",xtg->beginl, xtg->tag); - err_h(ebuf,ectx); - } - - for(l=xtg->begin;lend;l++) if (!isdigit(*l)) - { - sprintf(ebuf,"Warning: (line %d) Tag <%s> should be a positive number",xtg->beginl, xtg->tag); - err_h(ebuf,ectx); - } - } - if (strcmp(xtg->tag,"forgiveness")==0) - { - int l; - for(l=0;zarfian[l];l++) if (memcmp(xtg->begin,zarfian[l],strlen(zarfian[l]))==0) break; - if (!zarfian[l]) - { - sprintf(ebuf,"Warning: (line %d) should be one of: Merciful, Polite, Tough, Cruel",xtg->beginl); - err_h(ebuf,ectx); - } - } - } - if (xti->format>0) - { - for(i=0;format_registry[i];i++) if (strcmp(xtg->tag,format_registry[i])==0) break; - if (format_registry[i] && xti->format !=i) - { - sprintf(ebuf,"Warning: (line %d) Found <%s> tag, but story is identified as %s.",xtg->beginl, xtg->tag, format_registry[xti->format]); - err_h(ebuf,ectx); - } - } - if (strcmp(xtg->tag,"story")==0) - { - xti->format=-1; - xti->width=0; - xti->height=0; - } - -} - - - -void ifiction_parse(char *md, IFCloseTag close_tag, void *close_ctx, IFErrorHandler error_handler, void *error_ctx) -{ -char *xml, buffer[2400], *aep, *mda=md, ebuffer[512]; -struct XMLTag *parse=NULL, *xtg; -struct ifiction_info xti; -char BOM[3]={ 0xEF, 0xBB, 0xBF}; -xti.width=0; -xti.height=0; -xti.format=-1; -llp=1; -lnlst=md; - -while(*mda && isspace(*mda)) mda++; -if (memcmp(mda,BOM,3)==0) -{ mda+=3; - while(*mda && isspace(*mda)) mda++; -} - - -if (strncmp("",mda, - strlen("")) - && - strncmp("",mda, - strlen("")) - ) -{ - error_handler("Error: XML header not found.",error_ctx); - return; -} - -xml=strstr(md," not found",error_ctx); - return; - } -while(xml && *xml) -{ - char *bp, *ep, *tp; - while(*xml&&*xml!='<') xml++; - if (!*xml) break; - bp=xml; - tp=strchr(bp+1,'<'); - ep=strchr(bp+1,'>'); - if (!ep) break; - if (tp && tp < ep) - { xml=tp; continue; } - if (!tp) tp=ep+1; - if (bp[1]=='/') /* end tag */ - { - strncpy(buffer,bp+2,(ep-bp)-2); - buffer[(ep-bp)-2]=0; - if (parse && strcmp(buffer,parse->tag)==0) - { /* copasetic. Close the tag */ - xtg=parse; - parse=xtg->next; - xtg->end=ep-strlen(buffer)-2; - ifiction_validate_tag(xtg,&xti,error_handler, error_ctx); - close_tag(xtg,close_ctx); - free(xtg); - } - else - { - for(xtg=parse;xtg && strcmp(buffer,xtg->tag);xtg=xtg->next); - if (xtg) /* Intervening unclosed tags */ - { for(xtg=parse;xtg && strcmp(buffer,parse->tag);xtg=parse) - { - xtg->end=xml-1; - parse=xtg->next; - sprintf(ebuffer,"Error: (line %d) unclosed <%s> tag",xtg->beginl,xtg->tag); - error_handler(ebuffer,error_ctx); - ifiction_validate_tag(xtg,&xti,error_handler, error_ctx); - close_tag(xtg,close_ctx); - free(xtg); - } - xtg=parse; - if (xtg) - { - xtg->end=xml-1; - parse=xtg->next; - ifiction_validate_tag(xtg,&xti, error_handler, error_ctx); - close_tag(xtg,close_ctx); - free(xtg); - } - } - else - { - sprintf(ebuffer,"Error: (line %d) saw without <%s>",getln(xml), buffer,buffer); - error_handler(ebuffer,error_ctx); - } - } - - } - else if(*(ep-1)=='/' || bp[1]=='!') /* unterminated tag */ - { - /* Do nothing */ - } - else /* Terminated tag beginning */ - { - int i; - xtg=(struct XMLTag *)my_malloc(sizeof(struct XMLTag),"XML Tag"); - xtg->next=parse; - xtg->beginl=getln(bp); - for(i=0;bp[i+1]=='_' || bp[i+1]=='-' || isalnum(bp[i+1]);i++) - xtg->tag[i]=bp[i+1]; - if (i==0) - { xml=tp; - free(xtg); - continue; - } - parse=xtg; - parse->tag[i]=0; - strncpy(parse->fulltag,bp+1,ep-bp-1); - parse->fulltag[ep-bp-1]=0; - parse->begin=ep+1; - } - xml=tp; -} - while (parse) - { - xtg=parse; - xtg->end=aep-1; - parse=xtg->next; - sprintf(ebuffer,"Error: (line %d) Unclosed tag <%s>",xtg->beginl,xtg->tag); - ifiction_validate_tag(xtg,&xti,error_handler, error_ctx); - close_tag(xtg,close_ctx); - free(xtg); - } -} - -struct get_tag -{ - char *tag; - char *parent; - char *output; - char *target; -}; - -static void ifiction_null_eh(char *e, void *c) -{ - if (e || c) { } - -} - -static void ifiction_find_value(struct XMLTag *xtg, void *xti) -{ - struct get_tag *gt=(struct get_tag *)xti; - - if (gt->output && !gt->target) return; - if (gt->target && gt->output && strcmp(gt->output,gt->target)==0) { gt->target=NULL; free(gt->output); gt->output=NULL; } - if (((!xtg->next && !gt->parent) || (xtg->next && gt->parent && strcmp(xtg->next->tag,gt->parent)==0)) && - strcmp(xtg->tag,gt->tag)==0) - { - int32 l = xtg->end-xtg->begin; - - if (gt->output) free(gt->output); - gt->output=(char *)my_malloc(l+1, "ifiction tag buffer"); - memcpy(gt->output, xtg->begin, l); - gt->output[l]=0; - - } -} - - -char *ifiction_get_tag(char *md, char *p, char *t, char *from) -{ - struct get_tag gt; - gt.output=NULL; - gt.parent=p; - gt.tag=t; - gt.target=from; - ifiction_parse(md,ifiction_find_value,>,ifiction_null_eh,NULL); - if (gt.target){ if (gt.output) free(gt.output); return NULL; } - return gt.output; -} diff --git a/babel/ifiction.h b/babel/ifiction.h deleted file mode 100644 index 75ae946..0000000 --- a/babel/ifiction.h +++ /dev/null @@ -1,45 +0,0 @@ -/* ifiction.h declarations for the babel ifiction API - * (c) 2006 By L. Ross Raszewski - * - * This code is freely usable for all purposes. - * - * This work is licensed under the Creative Commons Attribution2.5 License. - * To view a copy of this license, visit - * http://creativecommons.org/licenses/by/2.5/ or send a letter to - * Creative Commons, - * 543 Howard Street, 5th Floor, - * San Francisco, California, 94105, USA. - * - */ - -#ifndef IFICTION_H -#define IFICTION_H - -#include "treaty.h" - -/* Babel's notion of an XML tag */ -struct XMLTag -{ - int32 beginl; /* Beginning line number */ - char tag[256]; /* name of the tag */ - char fulltag[256]; /* Full text of the opening tag */ - char *begin; /* Points to the beginning of the tag's content */ - char *end; /* Points to the end of the tag's content. - setting *end=0 will turn begin into a string - containing the tag's content (But if you do this, you - should restore the original value of *end before - allowing control to return to the ifiction parser) */ - char occurences[256]; /* Tables used internally to find missing required tags */ - char rocurrences[256]; - struct XMLTag *next; /* The tag's parent */ - -}; - -typedef void (*IFCloseTag)(struct XMLTag *, void *); -typedef void (*IFErrorHandler)(char *, void *); - - -void ifiction_parse(char *md, IFCloseTag close_tag, void *close_ctx, IFErrorHandler error_handler, void *error_ctx); -int32 ifiction_get_IFID(char *metadata, char *output, int32 output_extent); -char *ifiction_get_tag(char *md, char *p, char *t, char *from); -#endif diff --git a/babel/level9.c b/babel/level9.c deleted file mode 100644 index de855b0..0000000 --- a/babel/level9.c +++ /dev/null @@ -1,495 +0,0 @@ -/* level9.c Treaty of Babel module for Level 9 files - * 2006 By L. Ross Raszewski - * - * Note that this module will handle both bare Level 9 A-Code and - * Spectrum .SNA snapshots. It will not handle compressed .Z80 images. - * - * The Level 9 identification algorithm is based in part on the algorithm - * used by Paul David Doherty's l9cut program. - * - * This file depends on treaty_builder.h - * - * This file is public domain, but note that any changes to this file - * may render it noncompliant with the Treaty of Babel - */ - -#define FORMAT level9 -#define HOME_PAGE "http://www.if-legends.org/~l9memorial/html/home.html" -#define FORMAT_EXT ".l9,.sna" -#define NO_METADATA -#define NO_COVER - -#include "treaty_builder.h" -#include -#include -#include - -struct l9rec { - int32 length; - unsigned char chk; - char *ifid; -}; - - -static struct l9rec l9_registry[] = { - { 0x3a31, 0xe5, "LEVEL9-001-1" }, - { 0x8333, 0xb7, "LEVEL9-001-1" }, - { 0x7c6f, 0x0f, "LEVEL9-001-1" }, - { 0x72fa, 0x8b, "LEVEL9-001-1" }, - { 0x38dd, 0x31, "LEVEL9-001-A" }, - { 0x39c0, 0x44, "LEVEL9-001-B" }, - { 0x3a12, 0x8f, "LEVEL9-001-C" }, - { 0x37f1, 0x77, "LEVEL9-001-2" }, - { 0x844d, 0x50, "LEVEL9-001-2" }, - { 0x738e, 0x5b, "LEVEL9-001-2" }, - { 0x3900, 0x1c, "LEVEL9-001-3" }, - { 0x8251, 0x5f, "LEVEL9-001-3" }, - { 0x7375, 0xe5, "LEVEL9-001-3" }, - { 0x3910, 0xac, "LEVEL9-001-4" }, - { 0x7a78, 0x5e, "LEVEL9-001-4" }, - { 0x78d5, 0xe3, "LEVEL9-001-4" }, - { 0x3ad6, 0xa7, "LEVEL9-001-5" }, - { 0x38a5, 0x0f, "LEVEL9-001-6" }, - { 0x361e, 0x7e, "LEVEL9-001-7" }, - { 0x3934, 0x75, "LEVEL9-001-8" }, - { 0x3511, 0xcc, "LEVEL9-001-9" }, - { 0x593a, 0xaf, "LEVEL9-002-1" }, - { 0x7931, 0xb9, "LEVEL9-002-1" }, - { 0x6841, 0x4a, "LEVEL9-002-1" }, - { 0x57e6, 0x8a, "LEVEL9-002-2" }, - { 0x7cdf, 0xa5, "LEVEL9-002-2" }, - { 0x6bc0, 0x62, "LEVEL9-002-2" }, - { 0x5819, 0xcd, "LEVEL9-002-3" }, - { 0x7a0c, 0x97, "LEVEL9-002-3" }, - { 0x692c, 0x21, "LEVEL9-002-3" }, - { 0x579b, 0xad, "LEVEL9-002-4" }, - { 0x7883, 0xe2, "LEVEL9-002-4" }, - { 0x670a, 0x94, "LEVEL9-002-4" }, - { 0x5323, 0xb7, "LEVEL9-003" }, - { 0x6e60, 0x83, "LEVEL9-003" }, - { 0x5b58, 0x50, "LEVEL9-003" }, - { 0x63b6, 0x2e, "LEVEL9-003" }, - { 0x6968, 0x32, "LEVEL9-003" }, - { 0x5b50, 0x66, "LEVEL9-003" }, - { 0x6970, 0xd6, "LEVEL9-003" }, - { 0x5ace, 0x11, "LEVEL9-003" }, - { 0x6e5c, 0xf6, "LEVEL9-003" }, - { 0x1929, 0x00, "LEVEL9-004-DEMO" }, - { 0x40e0, 0x02, "LEVEL9-004-DEMO" }, - { 0x3ebb, 0x00, "LEVEL9-004-en" }, - { 0x3e4f, 0x00, "LEVEL9-004-en" }, - { 0x3e8f, 0x00, "LEVEL9-004-en" }, - { 0x0fd8, 0x00, "LEVEL9-004-en" }, - { 0x14a3, 0x00, "LEVEL9-004-en" }, - { 0x110f, 0x00, "LEVEL9-004-fr" }, - { 0x4872, 0x00, "LEVEL9-004-de" }, - { 0x4846, 0x00, "LEVEL9-004-de" }, - { 0x11f5, 0x00, "LEVEL9-004-de" }, - { 0x11f5, 0x00, "LEVEL9-004-de" }, - { 0x76f4, 0x5e, "LEVEL9-005" }, - { 0x5b16, 0x3b, "LEVEL9-005" }, - { 0x6c8e, 0xb6, "LEVEL9-005" }, - { 0x6f4d, 0xcb, "LEVEL9-005" }, - { 0x6f6a, 0xa5, "LEVEL9-005" }, - { 0x5e31, 0x7c, "LEVEL9-005" }, - { 0x6f70, 0x40, "LEVEL9-005" }, - { 0x6f6e, 0x78, "LEVEL9-005" }, - { 0x5a8e, 0xf2, "LEVEL9-005" }, - { 0x76f4, 0x5a, "LEVEL9-005" }, - { 0x630e, 0x8d, "LEVEL9-006" }, - { 0x630e, 0xbe, "LEVEL9-006" }, - { 0x6f0c, 0x95, "LEVEL9-006" }, - { 0x593a, 0x80, "LEVEL9-006" }, - { 0x6bd2, 0x65, "LEVEL9-006" }, - { 0x6dc0, 0x63, "LEVEL9-006" }, - { 0x58a6, 0x24, "LEVEL9-006" }, - { 0x6de8, 0x4c, "LEVEL9-006" }, - { 0x58a3, 0x38, "LEVEL9-006" }, - { 0x63be, 0xd6, "LEVEL9-007" }, - { 0x378c, 0x8d, "LEVEL9-007" }, - { 0x63be, 0x0a, "LEVEL9-007" }, - { 0x34b3, 0x20, "LEVEL9-008" }, - { 0x34b3, 0xc7, "LEVEL9-008" }, - { 0x34b3, 0x53, "LEVEL9-008" }, - { 0xb1a9, 0x80, "LEVEL9-009-1" }, - { 0x908e, 0x0d, "LEVEL9-009-1" }, - { 0xad41, 0xa8, "LEVEL9-009-1" }, - { 0xb1aa, 0xad, "LEVEL9-009-1" }, - { 0x8aab, 0xc0, "LEVEL9-009-1" }, - { 0xb0ec, 0xc2, "LEVEL9-009-1" }, - { 0xb19e, 0x92, "LEVEL9-009-1" }, - { 0x5ff0, 0xf8, "LEVEL9-009-1" }, - { 0x52aa, 0xdf, "LEVEL9-009-1" }, - { 0xab9d, 0x31, "LEVEL9-009-2" }, - { 0x8f6f, 0x0a, "LEVEL9-009-2" }, - { 0xa735, 0xf7, "LEVEL9-009-2" }, - { 0xab8b, 0xbf, "LEVEL9-009-2" }, - { 0x8ac8, 0x9a, "LEVEL9-009-2" }, - { 0xaf82, 0x83, "LEVEL9-009-2" }, - { 0x6024, 0x01, "LEVEL9-009-2" }, - { 0x6ffa, 0xdb, "LEVEL9-009-2" }, - { 0xae28, 0x87, "LEVEL9-009-3" }, - { 0x9060, 0xbb, "LEVEL9-009-3" }, - { 0xa9c0, 0x9e, "LEVEL9-009-3" }, - { 0xae16, 0x81, "LEVEL9-009-3" }, - { 0x8a93, 0x4f, "LEVEL9-009-3" }, - { 0xb3e6, 0xab, "LEVEL9-009-3" }, - { 0x6036, 0x3d, "LEVEL9-009-3" }, - { 0x723a, 0x69, "LEVEL9-009-3" }, - { 0xd188, 0x13, "LEVEL9-010-1" }, - { 0x9089, 0xce, "LEVEL9-010-1" }, - { 0xb770, 0x03, "LEVEL9-010-1" }, - { 0xd19b, 0xad, "LEVEL9-010-1" }, - { 0x8ab7, 0x68, "LEVEL9-010-1" }, - { 0xd183, 0x83, "LEVEL9-010-1" }, - { 0x5a38, 0xf7, "LEVEL9-010-1" }, - { 0x76a0, 0x3a, "LEVEL9-010-1" }, - { 0xc594, 0x03, "LEVEL9-010-2" }, - { 0x908d, 0x80, "LEVEL9-010-2" }, - { 0xb741, 0xb6, "LEVEL9-010-2" }, - { 0xc5a5, 0xfe, "LEVEL9-010-2" }, - { 0x8b1e, 0x84, "LEVEL9-010-2" }, - { 0xc58f, 0x65, "LEVEL9-010-2" }, - { 0x531a, 0xed, "LEVEL9-010-2" }, - { 0x7674, 0x0b, "LEVEL9-010-2" }, - { 0xd79f, 0xb5, "LEVEL9-010-3" }, - { 0x909e, 0x9f, "LEVEL9-010-3" }, - { 0xb791, 0xa1, "LEVEL9-010-3" }, - { 0xd7ae, 0x9e, "LEVEL9-010-3" }, - { 0x8b1c, 0xa8, "LEVEL9-010-3" }, - { 0xd79a, 0x57, "LEVEL9-010-3" }, - { 0x57e4, 0x19, "LEVEL9-010-3" }, - { 0x765e, 0xba, "LEVEL9-010-3" }, - { 0xbb93, 0x36, "LEVEL9-011-1" }, - { 0x898a, 0x43, "LEVEL9-011-1" }, - { 0x8970, 0x6b, "LEVEL9-011-1" }, - { 0xbb6e, 0xa6, "LEVEL9-011-1" }, - { 0x86d0, 0xb7, "LEVEL9-011-1" }, - { 0xbb6e, 0xad, "LEVEL9-011-1" }, - { 0x46ec, 0x64, "LEVEL9-011-1" }, - { 0x74e0, 0x92, "LEVEL9-011-1" }, - { 0xc58e, 0x4a, "LEVEL9-011-2" }, - { 0x8b9f, 0x61, "LEVEL9-011-2" }, - { 0x8b90, 0x4e, "LEVEL9-011-2" }, - { 0xc58e, 0x43, "LEVEL9-011-2" }, - { 0x8885, 0x22, "LEVEL9-011-2" }, - { 0x6140, 0x18, "LEVEL9-011-2" }, - { 0x6dbc, 0x97, "LEVEL9-011-2" }, - { 0xcb9a, 0x0f, "LEVEL9-011-3" }, - { 0x8af9, 0x61, "LEVEL9-011-3" }, - { 0x8aea, 0x4e, "LEVEL9-011-3" }, - { 0xcb9a, 0x08, "LEVEL9-011-3" }, - { 0x87e5, 0x0e, "LEVEL9-011-3" }, - { 0x640e, 0xc1, "LEVEL9-011-3" }, - { 0x7402, 0x07, "LEVEL9-011-3" }, - { 0xbba4, 0x94, "LEVEL9-012-1" }, - { 0xc0cf, 0x4e, "LEVEL9-012-1" }, - { 0x8afc, 0x07, "LEVEL9-012-1" }, - { 0x8feb, 0xba, "LEVEL9-012-1" }, - { 0xb4c9, 0x94, "LEVEL9-012-1" }, - { 0xc0bd, 0x57, "LEVEL9-012-1" }, - { 0x8ade, 0xf2, "LEVEL9-012-1" }, - { 0x4fd2, 0x9d, "LEVEL9-012-1" }, - { 0x5c7a, 0x44, "LEVEL9-012-1" }, - { 0x768c, 0xe8, "LEVEL9-012-1" }, - { 0xd0c0, 0x56, "LEVEL9-012-2" }, - { 0xd5e9, 0x6a, "LEVEL9-012-2" }, - { 0x8aec, 0x13, "LEVEL9-012-2" }, - { 0x8f6b, 0xfa, "LEVEL9-012-2" }, - { 0xb729, 0x51, "LEVEL9-012-2" }, - { 0xd5d7, 0x99, "LEVEL9-012-2" }, - { 0x8b0e, 0xfb, "LEVEL9-012-2" }, - { 0x4dac, 0xa8, "LEVEL9-012-2" }, - { 0x53a2, 0x1e, "LEVEL9-012-2" }, - { 0x76b0, 0x1d, "LEVEL9-012-2" }, - { 0xb6ac, 0xc6, "LEVEL9-012-3" }, - { 0xbb8f, 0x1a, "LEVEL9-012-3" }, - { 0x8aba, 0x0d, "LEVEL9-012-3" }, - { 0x8f71, 0x2f, "LEVEL9-012-3" }, - { 0xb702, 0xe4, "LEVEL9-012-3" }, - { 0xbb7d, 0x17, "LEVEL9-012-3" }, - { 0x8ab3, 0xc1, "LEVEL9-012-3" }, - { 0x4f96, 0x22, "LEVEL9-012-3" }, - { 0x5914, 0x22, "LEVEL9-012-3" }, - { 0x765e, 0x4f, "LEVEL9-012-3" }, - { 0x5eb9, 0x30, "LEVEL9-013" }, - { 0x5eb9, 0x5d, "LEVEL9-013" }, - { 0x5eb9, 0x6e, "LEVEL9-013" }, - { 0xb257, 0xf8, "LEVEL9-013" }, - { 0xb576, 0x2a, "LEVEL9-013" }, - { 0x8d78, 0x3a, "LEVEL9-013" }, - { 0x9070, 0x43, "LEVEL9-013" }, - { 0xb38c, 0x37, "LEVEL9-013" }, - { 0xb563, 0x6a, "LEVEL9-013" }, - { 0xb57c, 0x44, "LEVEL9-013" }, - { 0xb260, 0xe5, "LEVEL9-013" }, - { 0x8950, 0xa1, "LEVEL9-013" }, - { 0xb579, 0x89, "LEVEL9-013" }, - { 0x579e, 0x97, "LEVEL9-013" }, - { 0x69fe, 0x56, "LEVEL9-013" }, - { 0x6f1e, 0xda, "LEVEL9-013" }, - { 0x5671, 0xbc, "LEVEL9-014" }, - { 0x6fc6, 0x14, "LEVEL9-014" }, - { 0x5aa4, 0xc1, "LEVEL9-014" }, - { 0x7410, 0x5e, "LEVEL9-014" }, - { 0x5aa4, 0xc1, "LEVEL9-014" }, - { 0x5aa4, 0xc1, "LEVEL9-014" }, - { 0xb797, 0x1f, "LEVEL9-014" }, - { 0xbaca, 0x3a, "LEVEL9-014" }, - { 0x8c46, 0xf0, "LEVEL9-014" }, - { 0x8f51, 0xb2, "LEVEL9-014" }, - { 0xb451, 0xa8, "LEVEL9-014" }, - { 0xbab2, 0x87, "LEVEL9-014" }, - { 0xbac7, 0x7f, "LEVEL9-014" }, - { 0xb7a0, 0x7e, "LEVEL9-014" }, - { 0x8a60, 0x2a, "LEVEL9-014" }, - { 0xbac4, 0x80, "LEVEL9-014" }, - { 0x579a, 0x2a, "LEVEL9-014" }, - { 0x5a50, 0xa9, "LEVEL9-014" }, - { 0x6108, 0xdd, "LEVEL9-014" }, - { 0x506c, 0xf0, "LEVEL9-015" }, - { 0x505d, 0x32, "LEVEL9-015" }, - { 0xa398, 0x82, "LEVEL9-015" }, - { 0xa692, 0xd1, "LEVEL9-015" }, - { 0x8d56, 0xd3, "LEVEL9-015" }, - { 0x903f, 0x6b, "LEVEL9-015" }, - { 0xa4e2, 0xa6, "LEVEL9-015" }, - { 0xa67c, 0xb8, "LEVEL9-015" }, - { 0xa69e, 0x6c, "LEVEL9-015" }, - { 0xa3a4, 0xdf, "LEVEL9-015" }, - { 0x8813, 0x11, "LEVEL9-015" }, - { 0xa698, 0x41, "LEVEL9-015" }, - { 0x5500, 0x50, "LEVEL9-015" }, - { 0x6888, 0x8d, "LEVEL9-015" }, - { 0x6da0, 0xb8, "LEVEL9-015" }, - { 0x6064, 0xbd, "LEVEL9-016" }, - { 0x6064, 0x01, "LEVEL9-016" }, - { 0x6047, 0x6c, "LEVEL9-016" }, - { 0x6064, 0xda, "LEVEL9-016" }, - { 0x6064, 0x95, "LEVEL9-016" }, - { 0x60c4, 0x28, "LEVEL9-016" }, - { 0x5cb7, 0xfe, "LEVEL9-016" }, - { 0x5ca1, 0x33, "LEVEL9-016" }, - { 0x5cb7, 0x64, "LEVEL9-016" }, - { 0x7d16, 0xe6, "LEVEL9-016" }, - { 0x639c, 0x8b, "LEVEL9-016" }, - { 0x60f7, 0x68, "LEVEL9-016" }, - { 0x772f, 0xca, "LEVEL9-016" }, - { 0x7cff, 0xf8, "LEVEL9-016" }, - { 0x7cf8, 0x24, "LEVEL9-016" }, - { 0x7d14, 0xe8, "LEVEL9-016" }, - { 0x7c55, 0x18, "LEVEL9-016" }, - { 0x5f43, 0xca, "LEVEL9-016" }, - { 0xc132, 0x14, "LEVEL9-017-1" }, - { 0xbeab, 0x2d, "LEVEL9-017-1" }, - { 0x9058, 0xcf, "LEVEL9-017-1" }, - { 0xbe94, 0xcc, "LEVEL9-017-1" }, - { 0x8a21, 0xf4, "LEVEL9-017-1" }, - { 0x55ce, 0xa1, "LEVEL9-017-1" }, - { 0x5cbc, 0xa5, "LEVEL9-017-1" }, - { 0x762e, 0x82, "LEVEL9-017-1" }, - { 0x99bd, 0x65, "LEVEL9-017-2" }, - { 0x8f43, 0xc9, "LEVEL9-017-2" }, - { 0x8a12, 0xe3, "LEVEL9-017-2" }, - { 0x54a6, 0xa9, "LEVEL9-017-2" }, - { 0x5932, 0x4e, "LEVEL9-017-2" }, - { 0x5bd6, 0x35, "LEVEL9-017-2" }, - { 0xbcb6, 0x7a, "LEVEL9-017-3 (Amiga/PC/ST)" }, - { 0x90ac, 0x68, "LEVEL9-017-3" }, - { 0x8a16, 0xcc, "LEVEL9-017-3" }, - { 0x51bc, 0xe3, "LEVEL9-017-3" }, - { 0x5860, 0x95, "LEVEL9-017-3" }, - { 0x6fa8, 0xa4, "LEVEL9-017-3" }, - { 0x5fab, 0x5c, "LEVEL9-018" }, - { 0x5fab, 0x2f, "LEVEL9-018" }, - { 0x7b31, 0x6e, "LEVEL9-018" }, - { 0x67a3, 0x9d, "LEVEL9-018" }, - { 0x6bf8, 0x3f, "LEVEL9-018" }, - { 0x7363, 0x65, "LEVEL9-018" }, - { 0x7b2f, 0x70, "LEVEL9-018" }, - { 0x7b2f, 0x70, "LEVEL9-018" }, - { 0x6541, 0x02, "LEVEL9-018" }, - { 0x5834, 0x42, "LEVEL9-019-1" }, - { 0x765d, 0xcd, "LEVEL9-019-1" }, - { 0x6ce5, 0x58, "LEVEL9-019-1" }, - { 0x56dd, 0x51, "LEVEL9-019-2" }, - { 0x6e58, 0x07, "LEVEL9-019-2" }, - { 0x68da, 0xc1, "LEVEL9-019-2" }, - { 0x5801, 0x53, "LEVEL9-019-3" }, - { 0x7e98, 0x6a, "LEVEL9-019-3" }, - { 0x6c67, 0x9a, "LEVEL9-019-3" }, - { 0x54a4, 0x01, "LEVEL9-019-4" }, - { 0x81e2, 0xd5, "LEVEL9-019-4" }, - { 0x6d91, 0xb9, "LEVEL9-019-4" }, - { 0x5828, 0xbd, "LEVEL9-020" }, - { 0x6d84, 0xf9, "LEVEL9-020" }, - { 0x6d84, 0xc8, "LEVEL9-020" }, - { 0x6030, 0x47, "LEVEL9-020" }, - { 0x772b, 0xcd, "LEVEL9-020" }, - { 0x546c, 0xb7, "LEVEL9-020" }, - { 0x7cd9, 0x0c, "LEVEL9-020" }, - { 0x60dd, 0xf2, "LEVEL9-020" }, - { 0x6161, 0xf3, "LEVEL9-020" }, - { 0x788d, 0x72, "LEVEL9-020" }, - { 0x7cd7, 0x0e, "LEVEL9-020" }, - { 0x5ebb, 0xf1, "LEVEL9-020" }, - - { 0, 0, NULL } -}; - - - -static int32 read_l9_int(unsigned char *sf) -{ - return ((int32) sf[1]) << 8 | sf[0]; - -} -static int v2_recognition (unsigned char *sf, int32 extent, int32 *l, unsigned char *c) -{ - int32 i, j; - for (i=0;i0x4000) && (*l<=0xdb00))) - if ((*l!=0) && (sf[i+0x0d] == 0)) - for (j=i;j0x0fd0) && (end <= (extent - 2)) && - (((read_l9_int(sf+i+2) + read_l9_int(sf+i+4))==read_l9_int(sf+i+6)) - && (read_l9_int(sf+i+2) != 0) && (read_l9_int(sf+i+4)) != 0) && - (((read_l9_int(sf+i+6) + read_l9_int(sf+i+8)) == read_l9_int(sf+i+10)) - && ((sf[i + 18] == 0x2a) || (sf[i + 18] == 0x2c)) - && (sf[i + 19] == 0) && (sf[i + 20] == 0) && (sf[i + 21] == 0))) - ll = 2; - } - if (ll>1) - { - *c=0; - if (phase==3) ll=1; - else - { char checksum=0; - *c = sf[end]; - for (j=i;j<=end;j++) - checksum += sf[j]; - if (!checksum) ll=1; - else ll=0; - } - } else ll=0; - } - - if (ll) return *l < 0x8500 ? 3:4; - return 0; -} -static char *get_l9_ifid(int32 length, unsigned char chk) -{ - int i; - for(i=0;l9_registry[i].length;i++) - if (length==l9_registry[i].length && chk==l9_registry[i].chk) return l9_registry[i].ifid; - return NULL; -} -static int get_l9_version(unsigned char *sf, int32 extent, char **ifid) -{ - int i; - int32 l; - unsigned char c; - if (v2_recognition(sf,extent, &l, &c)) { *ifid=get_l9_ifid(l,c); return 2; } - l=0; c=0; - i=v3_recognition_phase(1,sf,extent, &l, &c); - if (i) { *ifid=get_l9_ifid(l,c); return i; } - if (v1_recognition(sf,extent, ifid)) return 1; - l=0; c=0; - i=v3_recognition_phase(2,sf,extent, &l, &c); - if (i) { *ifid=get_l9_ifid(l,c); return i; } - i=v3_recognition_phase(3,sf,extent, &l, &c); - *ifid=NULL; - return i; -} - -static int32 claim_story_file(void *story, int32 extent) -{ - char *ifid=NULL; - if (get_l9_version((unsigned char *) story,extent, &ifid)) - if (ifid) return VALID_STORY_FILE_RV; - else return NO_REPLY_RV; - return INVALID_STORY_FILE_RV; -} - - - -static int32 get_story_file_IFID(void *story_file, int32 extent, char *output, int32 output_extent) -{ - char *ifid=NULL; - int i=get_l9_version((unsigned char *)story_file, extent, &ifid); - if (!i) return INVALID_STORY_FILE_RV; - if (ifid) - { - ASSERT_OUTPUT_SIZE((signed) strlen(ifid)+1); - strcpy(output,ifid); - return 1; - } - ASSERT_OUTPUT_SIZE(10); - sprintf(output,"LEVEL9-%d-",i); - return INCOMPLETE_REPLY_RV; -} diff --git a/babel/magscrolls.c b/babel/magscrolls.c deleted file mode 100644 index c21c922..0000000 --- a/babel/magscrolls.c +++ /dev/null @@ -1,124 +0,0 @@ -/* magscrolls.c Treaty of Babel module for Z-code files - * 2006 By L. Ross Raszewski - * - * This file depends on treaty_builder.h - * - * This file is public domain, but note that any changes to this file - * may render it noncompliant with the Treaty of Babel - */ - -#define FORMAT magscrolls -#define HOME_PAGE "http://www.if-legends.org/~msmemorial/memorial.htm" -#define FORMAT_EXT ".mag" -#define NO_COVER -#define NO_METADATA - -#include "treaty_builder.h" -#include -#include - -struct maginfo -{ - int gv; - char header[21]; - char *title; - int bafn; - int year; - char *ifid; - char *author; - char *meta; -}; - - -static struct maginfo manifest[] = { - { 0, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", - "The Pawn", - 0, - 1985, - "MAGNETIC-1", - "Rob Steggles", - }, - { 1, "\000\004\000\001\007\370\000\000\340\000\000\000\041\064\000\000\040\160\000\000", - "Guild of Thieves", - 0, - 1987, - "MAGNETIC-2", - "Rob Steggles", - }, - { 2, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", - "Jinxter", - 0, - 1987, - "MAGNETIC-3", - "Georgina Sinclair and Michael Bywater", - }, - { 4, "\000\004\000\001\045\140\000\001\000\000\000\000\161\017\000\000\035\210\000\001", - "Corruption", - 0, - 1988, - "MAGNETIC-4", - "Rob Steggles and Hugh Steers", - }, - { 4, "\000\004\000\001\044\304\000\001\000\000\000\000\134\137\000\000\040\230\000\001", - "Fish!", - 0, - 1988, - "MAGNETIC-5", - "John Molloy, Pete Kemp, Phil South, Rob Steggles", - }, - { 4, "\000\003\000\000\377\000\000\000\340\000\000\000\221\000\000\000\036\000\000\001", - "Corruption", - 0, - 1988, - "MAGNETIC-4", - "Rob Steggles and Hugh Steers", - }, - { 4, "\000\003\000\001\000\000\000\000\340\000\000\000\175\000\000\000\037\000\000\001", - "Fish!", - 0, - 1988, - "MAGNETIC-5", - "John Molloy, Pete Kemp, Phil South, Rob Steggles", - }, - { 4, "\000\003\000\000\335\000\000\000\140\000\000\000\064\000\000\000\023\000\000\000", - "Myth", - 0, - 1989, - "MAGNETIC-6", - "Paul Findley", - }, - { 4, "\000\004\000\001\122\074\000\001\000\000\000\000\114\146\000\000\057\240\000\001", - "Wonderland", - 0, - 1990, - "MAGNETIC-7", - "David Bishop", - }, - { 0, "0", NULL, 0, 0, NULL, NULL } - }; - -static int32 get_story_file_IFID(void *story_file, int32 extent, char *output, int32 output_extent) -{ - int i; - unsigned char *sf=(unsigned char *)story_file; - if (extent < 42) return INVALID_STORY_FILE_RV; - - for(i=0;manifest[i].title;i++) - if ((sf[13]<3 && manifest[i].gv==sf[13]) || memcmp(manifest[i].header,sf+12,20)==0) - { - ASSERT_OUTPUT_SIZE(((int32) strlen(manifest[i].ifid)+1)); - strcpy(output,manifest[i].ifid); - return 1; - } - strcpy(output,"MAGNETIC-"); - return INCOMPLETE_REPLY_RV; -} - -static int32 claim_story_file(void *story_file, int32 extent) -{ - if (extent<42 || - memcmp(story_file,"MaSc",4) - ) return INVALID_STORY_FILE_RV; - return VALID_STORY_FILE_RV; -} - diff --git a/babel/md5.c b/babel/md5.c deleted file mode 100644 index c35d96c..0000000 --- a/babel/md5.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.c is L. Peter Deutsch - . Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include - in library. - 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. - 2002-02-21 lpd Added missing #include in test program. - 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). - 1999-05-03 lpd Original version. - */ - -#include "md5.h" -#include - -#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ -#ifdef ARCH_IS_BIG_ENDIAN -# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) -#else -# define BYTE_ORDER 0 -#endif - -#define T_MASK ((md5_word_t)~0) -#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) -#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) -#define T3 0x242070db -#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) -#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) -#define T6 0x4787c62a -#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) -#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) -#define T9 0x698098d8 -#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) -#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) -#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) -#define T13 0x6b901122 -#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) -#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) -#define T16 0x49b40821 -#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) -#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) -#define T19 0x265e5a51 -#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) -#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) -#define T22 0x02441453 -#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) -#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) -#define T25 0x21e1cde6 -#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) -#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) -#define T28 0x455a14ed -#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) -#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) -#define T31 0x676f02d9 -#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) -#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) -#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) -#define T35 0x6d9d6122 -#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) -#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) -#define T38 0x4bdecfa9 -#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) -#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) -#define T41 0x289b7ec6 -#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) -#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) -#define T44 0x04881d05 -#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) -#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) -#define T47 0x1fa27cf8 -#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) -#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) -#define T50 0x432aff97 -#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) -#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) -#define T53 0x655b59c3 -#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) -#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) -#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) -#define T57 0x6fa87e4f -#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) -#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) -#define T60 0x4e0811a1 -#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) -#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) -#define T63 0x2ad7d2bb -#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) - - -static void -md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) -{ - md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - md5_word_t t; -#if BYTE_ORDER > 0 - /* Define storage only for big-endian CPUs. */ - md5_word_t X[16]; -#else - /* Define storage for little-endian or both types of CPUs. */ - md5_word_t xbuf[16]; - const md5_word_t *X; -#endif - - { -#if BYTE_ORDER == 0 - /* - * Determine dynamically whether this is a big-endian or - * little-endian machine, since we can use a more efficient - * algorithm on the latter. - */ - static const int w = 1; - - if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ -#endif -#if BYTE_ORDER <= 0 /* little-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if (!((data - (const md5_byte_t *)0) & 3)) { - /* data are properly aligned */ - X = (const md5_word_t *)data; - } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } - } -#endif -#if BYTE_ORDER == 0 - else /* dynamic big-endian */ -#endif -#if BYTE_ORDER >= 0 /* big-endian */ - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const md5_byte_t *xp = data; - int i; - -# if BYTE_ORDER == 0 - X = xbuf; /* (dynamic only) */ -# else -# define xbuf X /* (static only) */ -# endif - for (i = 0; i < 16; ++i, xp += 4) - xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - } -#endif - } - -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + F(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 7, T1); - SET(d, a, b, c, 1, 12, T2); - SET(c, d, a, b, 2, 17, T3); - SET(b, c, d, a, 3, 22, T4); - SET(a, b, c, d, 4, 7, T5); - SET(d, a, b, c, 5, 12, T6); - SET(c, d, a, b, 6, 17, T7); - SET(b, c, d, a, 7, 22, T8); - SET(a, b, c, d, 8, 7, T9); - SET(d, a, b, c, 9, 12, T10); - SET(c, d, a, b, 10, 17, T11); - SET(b, c, d, a, 11, 22, T12); - SET(a, b, c, d, 12, 7, T13); - SET(d, a, b, c, 13, 12, T14); - SET(c, d, a, b, 14, 17, T15); - SET(b, c, d, a, 15, 22, T16); -#undef SET - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + G(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 1, 5, T17); - SET(d, a, b, c, 6, 9, T18); - SET(c, d, a, b, 11, 14, T19); - SET(b, c, d, a, 0, 20, T20); - SET(a, b, c, d, 5, 5, T21); - SET(d, a, b, c, 10, 9, T22); - SET(c, d, a, b, 15, 14, T23); - SET(b, c, d, a, 4, 20, T24); - SET(a, b, c, d, 9, 5, T25); - SET(d, a, b, c, 14, 9, T26); - SET(c, d, a, b, 3, 14, T27); - SET(b, c, d, a, 8, 20, T28); - SET(a, b, c, d, 13, 5, T29); - SET(d, a, b, c, 2, 9, T30); - SET(c, d, a, b, 7, 14, T31); - SET(b, c, d, a, 12, 20, T32); -#undef SET - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + H(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 5, 4, T33); - SET(d, a, b, c, 8, 11, T34); - SET(c, d, a, b, 11, 16, T35); - SET(b, c, d, a, 14, 23, T36); - SET(a, b, c, d, 1, 4, T37); - SET(d, a, b, c, 4, 11, T38); - SET(c, d, a, b, 7, 16, T39); - SET(b, c, d, a, 10, 23, T40); - SET(a, b, c, d, 13, 4, T41); - SET(d, a, b, c, 0, 11, T42); - SET(c, d, a, b, 3, 16, T43); - SET(b, c, d, a, 6, 23, T44); - SET(a, b, c, d, 9, 4, T45); - SET(d, a, b, c, 12, 11, T46); - SET(c, d, a, b, 15, 16, T47); - SET(b, c, d, a, 2, 23, T48); -#undef SET - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + I(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 6, T49); - SET(d, a, b, c, 7, 10, T50); - SET(c, d, a, b, 14, 15, T51); - SET(b, c, d, a, 5, 21, T52); - SET(a, b, c, d, 12, 6, T53); - SET(d, a, b, c, 3, 10, T54); - SET(c, d, a, b, 10, 15, T55); - SET(b, c, d, a, 1, 21, T56); - SET(a, b, c, d, 8, 6, T57); - SET(d, a, b, c, 15, 10, T58); - SET(c, d, a, b, 6, 15, T59); - SET(b, c, d, a, 13, 21, T60); - SET(a, b, c, d, 4, 6, T61); - SET(d, a, b, c, 11, 10, T62); - SET(c, d, a, b, 2, 15, T63); - SET(b, c, d, a, 9, 21, T64); -#undef SET - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; -} - -void -md5_init(md5_state_t *pms) -{ - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - pms->abcd[3] = 0x10325476; -} - -void -md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) -{ - const md5_byte_t *p = data; - int left = nbytes; - int offset = (pms->count[0] >> 3) & 63; - md5_word_t nbits = (md5_word_t)(nbytes << 3); - - if (nbytes <= 0) - return; - - /* Update the message length. */ - pms->count[1] += nbytes >> 29; - pms->count[0] += nbits; - if (pms->count[0] < nbits) - pms->count[1]++; - - /* Process an initial partial block. */ - if (offset) { - int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buf); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); - - /* Process a final partial block. */ - if (left) - memcpy(pms->buf, p, left); -} - -void -md5_finish(md5_state_t *pms, md5_byte_t digest[16]) -{ - static const md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); - /* Pad to 56 bytes mod 64. */ - md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); - /* Append the length. */ - md5_append(pms, data, 8); - for (i = 0; i < 16; ++i) - digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); -} diff --git a/babel/md5.h b/babel/md5.h deleted file mode 100644 index 698c995..0000000 --- a/babel/md5.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.h is L. Peter Deutsch - . Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Removed support for non-ANSI compilers; removed - references to Ghostscript; clarified derivation from RFC 1321; - now handles byte order either statically or dynamically. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke . - 1999-05-03 lpd Original version. - */ - -#ifndef md5_INCLUDED -# define md5_INCLUDED - -/* - * This package supports both compile-time and run-time determination of CPU - * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be - * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is - * defined as non-zero, the code will be compiled to run only on big-endian - * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to - * run on either big- or little-endian CPUs, but will run slightly less - * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. - */ - -typedef unsigned char md5_byte_t; /* 8-bit byte */ -typedef unsigned int md5_word_t; /* 32-bit word */ - -/* Define the state of the MD5 Algorithm. */ -typedef struct md5_state_s { - md5_word_t count[2]; /* message length in bits, lsw first */ - md5_word_t abcd[4]; /* digest buffer */ - md5_byte_t buf[64]; /* accumulate block */ -} md5_state_t; - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Initialize the algorithm. */ -void md5_init(md5_state_t *pms); - -/* Append a string to the message. */ -void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); - -/* Finish the message and return the digest. */ -void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); - -#ifdef __cplusplus -} /* end extern "C" */ -#endif - -#endif /* md5_INCLUDED */ diff --git a/babel/misc.c b/babel/misc.c deleted file mode 100644 index 982927f..0000000 --- a/babel/misc.c +++ /dev/null @@ -1,19 +0,0 @@ -/* misc.h : miscellany for babel - * This file is public domain - * 2006 by L. Ross Raszewski - */ - -#include -#include - -void *my_malloc(int size, char *rs) -{ - void *buf=calloc(size,1); - if (size && !buf) - { - fprintf(stderr,"Error: Memory exceeded (%d for %s)!\n",size,rs); - exit(2); - } - return buf; -} - diff --git a/babel/modules.h b/babel/modules.h deleted file mode 100644 index cc799ee..0000000 --- a/babel/modules.h +++ /dev/null @@ -1,70 +0,0 @@ -/* modules.h Declaration of treaty modules for the babel program - * (c) 2006 By L. Ross Raszewski - * - * This code is freely usable for all purposes. - * - * This work is licensed under the Creative Commons Attribution2.5 License. - * To view a copy of this license, visit - * http://creativecommons.org/licenses/by/2.5/ or send a letter to - * Creative Commons, - * 543 Howard Street, 5th Floor, - * San Francisco, California, 94105, USA. - * - * This file depends upon treaty.h and all the references treaty modules - * - * Persons wishing to add support for a new module to babel need only - * add a line in the form below. New modules should be positioned according - * to their popularity. If this file is being used in tandem with register.c - * (as it is in babel), then being dishonest about the popularity of an added - * system will make the program non-compliant with the treaty of Babel - * - * REGISTER_NAME is used as a placeholder for formats which are specified - * as existing by the treaty but for which no handler yet exists. - * remove the REGISTER_NAME for any format which has a registered treaty. - */ - - -#include "treaty.h" -#undef REGISTER_TREATY -#undef REGISTER_CONTAINER -#undef REGISTER_NAME -#ifdef TREATY_REGISTER -#ifdef CONTAINER_REGISTER -#ifdef FORMAT_REGISTER -#define REGISTER_TREATY(x) #x, -#define REGISTER_NAME(x) #x, -#define REGISTER_CONTAINER(x) -#else -#define REGISTER_TREATY(x) -#define REGISTER_CONTAINER(x) x##_treaty, -#define REGISTER_NAME(x) -#endif -#else -#define REGISTER_TREATY(x) x##_treaty, -#define REGISTER_CONTAINER(x) -#define REGISTER_NAME(x) -#endif -#else -#define REGISTER_TREATY(x) int32 x##_treaty(int32, void *, int32, void *, int32); -#define REGISTER_CONTAINER(x) int32 x##_treaty(int32, void *, int32, void *, int32); -#define REGISTER_NAME(x) -#endif - - -REGISTER_CONTAINER(blorb) -REGISTER_TREATY(zcode) -REGISTER_TREATY(glulx) -REGISTER_TREATY(tads2) -REGISTER_TREATY(tads3) -REGISTER_TREATY(hugo) -REGISTER_TREATY(alan) -REGISTER_TREATY(adrift) -REGISTER_TREATY(level9) -REGISTER_TREATY(agt) -REGISTER_TREATY(magscrolls) -REGISTER_TREATY(advsys) -REGISTER_TREATY(executable) - - - - diff --git a/babel/modules.h.gch b/babel/modules.h.gch deleted file mode 100644 index 99db82c..0000000 Binary files a/babel/modules.h.gch and /dev/null differ diff --git a/babel/register.c b/babel/register.c deleted file mode 100644 index 22bbed5..0000000 --- a/babel/register.c +++ /dev/null @@ -1,36 +0,0 @@ -/* register.c Register modules for the babel handler api - * - * 2006 by L. Ross Raszewski - * - * This code is freely usable for all purposes. - * - * This work is licensed under the Creative Commons Attribution2.5 License. - * To view a copy of this license, visit - * http://creativecommons.org/licenses/by/2.5/ or send a letter to - * Creative Commons, - * 543 Howard Street, 5th Floor, - * San Francisco, California, 94105, USA. - * - * This file depends on modules.h - * - * The purpose of this file is to create the treaty_registry array. - * This array is a null-terminated list of the known treaty modules. - */ - -#include -#include "modules.h" - - -TREATY treaty_registry[] = { - #define TREATY_REGISTER - #include "modules.h" - NULL - }; - -TREATY container_registry[] = { - #define CONTAINER_REGISTER - #include "modules.h" - NULL - -}; - diff --git a/babel/register_ifiction.c b/babel/register_ifiction.c deleted file mode 100644 index 55fe9e2..0000000 --- a/babel/register_ifiction.c +++ /dev/null @@ -1,29 +0,0 @@ -/* register_ifiction.c Register modules for babel's ifiction API - * - * 2006 by L. Ross Raszewski - * - * This code is freely usable for all purposes. - * - * This work is licensed under the Creative Commons Attribution2.5 License. - * To view a copy of this license, visit - * http://creativecommons.org/licenses/by/2.5/ or send a letter to - * Creative Commons, - * 543 Howard Street, 5th Floor, - * San Francisco, California, 94105, USA. - * - * This file depends on modules.h - * - * This version of register.c is stripped down to include only the - * needed functionality for the ifiction api - */ - -#include -#include "treaty.h" - -char *format_registry[] = { - #define TREATY_REGISTER - #define CONTAINER_REGISTER - #define FORMAT_REGISTER - #include "modules.h" - NULL -}; diff --git a/babel/tads.c b/babel/tads.c deleted file mode 100644 index bde1e5a..0000000 --- a/babel/tads.c +++ /dev/null @@ -1,1827 +0,0 @@ -/* - * tads.c - Treaty of Babel common functions for tads2 and tads3 modules - * - * This file depends on treaty_builder.h - * - * This file is public domain, but note that any changes to this file may - * render it noncompliant with the Treaty of Babel - * - * Modified - *. 04/08/2006 LRRaszewski - changed babel API calls to threadsafe versions - *. 04/08/2006 MJRoberts - initial implementation - */ - - -#include "treaty.h" -#include -#include -#include -#include -#include "tads.h" -#include "md5.h" - -#define ASSERT_OUTPUT_SIZE(x) \ - do { if (output_extent < (x)) return INVALID_USAGE_RV; } while (0) - -#define T2_SIGNATURE "TADS2 bin\012\015\032" -#define T3_SIGNATURE "T3-image\015\012\032" - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -/* ------------------------------------------------------------------------ */ -/* - * private structures - */ - -/* - * resource information structure - this encapsulates the location and size - * of a binary resource object embedded in a story file - */ -typedef struct resinfo resinfo; -struct resinfo -{ - /* pointer and length of the data in the story file buffer */ - const char *ptr; - int32 len; - - /* tads major version (currently, 2 or 3) */ - int tads_version; -}; - -/* - * Name/value pair list entry - */ -typedef struct valinfo valinfo; -struct valinfo -{ - const char *name; - size_t name_len; - - /* value string */ - char *val; - size_t val_len; - - /* next entry in the list */ - valinfo *nxt; -}; - - -/* ------------------------------------------------------------------------ */ -/* - * forward declarations - */ -static valinfo *parse_game_info(const void *story_file, int32 story_len, - int *version); -static int find_resource(const void *story_file, int32 story_len, - const char *resname, resinfo *info); -static int find_cover_art(const void *story_file, int32 story_len, - resinfo *resp, int32 *image_format, - int32 *width, int32 *height); -static int t2_find_res(const void *story_file, int32 story_len, - const char *resname, resinfo *info); -static int t3_find_res(const void *story_file, int32 story_len, - const char *resname, resinfo *info); -static valinfo *find_by_key(valinfo *list_head, const char *key); -static void delete_valinfo_list(valinfo *head); -static int32 generate_md5_ifid(void *story_file, int32 extent, - char *output, int32 output_extent); -static int32 synth_ifiction(valinfo *vals, int tads_version, - char *buf, int32 bufsize, - void *story_file, int32 extent); -static int get_png_dim(const void *img, int32 extent, - int32 *xout, int32 *yout); -static int get_jpeg_dim(const void *img, int32 extent, - int32 *xout, int32 *yout); - - - -/* ------------------------------------------------------------------------ */ -/* - * Get the IFID for a given story file. - */ -int32 tads_get_story_file_IFID(void *story_file, int32 extent, - char *output, int32 output_extent) -{ - valinfo *vals; - - /* if we have GameInfo, try looking for an IFID there */ - if ((vals = parse_game_info(story_file, extent, 0)) != 0) - { - valinfo *val; - int found = 0; - - /* find the "IFID" key */ - if ((val = find_by_key(vals, "IFID")) != 0) - { - char *p; - - /* copy the output as a null-terminated string */ - ASSERT_OUTPUT_SIZE((int32)val->val_len + 1); - memcpy(output, val->val, val->val_len); - output[val->val_len] = '\0'; - - /* - * count up the IFIDs in the buffer - there might be more than - * one, separated by commas - */ - for (found = 1, p = output ; *p != '\0' ; ++p) - { - /* if this is a comma, it delimits a new IFID */ - if (*p == ',') - ++found; - } - } - - /* delete the GameInfo list */ - delete_valinfo_list(vals); - - /* if we found an IFID, indicate how many results we found */ - if (found != 0) - return found; - } - - /* - * we didn't find an IFID in the GameInfo, so generate a default IFID - * using the MD5 method - */ - return generate_md5_ifid(story_file, extent, output, output_extent); -} - -/* - * Get the size of the ifiction metadata for the game - */ -int32 tads_get_story_file_metadata_extent(void *story_file, int32 extent) -{ - valinfo *vals; - int32 ret; - int ver; - - /* - * First, make sure we have a GameInfo record. If we don't, simply - * indicate that there's no metadata to fetch. - */ - if ((vals = parse_game_info(story_file, extent, &ver)) == 0) - return NO_REPLY_RV; - - /* - * Run the ifiction synthesizer with no output buffer, to calculate the - * size we need. - */ - ret = synth_ifiction(vals, ver, 0, 0, story_file, extent); - - /* delete the value list */ - delete_valinfo_list(vals); - - /* return the required size */ - return ret; -} - -/* - * Get the ifiction metadata for the game - */ -int32 tads_get_story_file_metadata(void *story_file, int32 extent, - char *buf, int32 bufsize) -{ - valinfo *vals; - int32 ret; - int ver; - - /* make sure we have metadata to fetch */ - if ((vals = parse_game_info(story_file, extent, &ver)) == 0) - return NO_REPLY_RV; - - /* synthesize the ifiction data into the output buffer */ - ret = synth_ifiction(vals, ver, buf, bufsize, story_file, extent); - - /* if that required more space than we had available, return an error */ - if (ret > bufsize) - ret = INVALID_USAGE_RV; - - /* delete the value list */ - delete_valinfo_list(vals); - - /* return the result */ - return ret; -} - -/* - * Get the size of the cover art - */ -int32 tads_get_story_file_cover_extent(void *story_file, int32 story_len) -{ - resinfo res; - - /* look for the cover art resource */ - if (find_cover_art(story_file, story_len, &res, 0, 0, 0)) - return res.len; - else - return NO_REPLY_RV; -} - -/* - * Get the format of the cover art - */ -int32 tads_get_story_file_cover_format(void *story_file, int32 story_len) -{ - int32 typ; - - /* look for CoverArt.jpg */ - if (find_cover_art(story_file, story_len, 0, &typ, 0, 0)) - return typ; - else - return NO_REPLY_RV; -} - -/* - * Get the cover art data - */ -int32 tads_get_story_file_cover(void *story_file, int32 story_len, - void *outbuf, int32 output_extent) -{ - resinfo res; - - /* look for CoverArt.jpg, then for CoverArt.png */ - if (find_cover_art(story_file, story_len, &res, 0, 0, 0)) - { - /* got it - copy the data to the buffer */ - ASSERT_OUTPUT_SIZE(res.len); - memcpy(outbuf, res.ptr, res.len); - - /* success */ - return res.len; - } - - /* otherwise, we didn't find it */ - return NO_REPLY_RV; -} - -/* ------------------------------------------------------------------------ */ -/* - * Generate a default IFID using the MD5 hash method - */ -static int32 generate_md5_ifid(void *story_file, int32 extent, - char *output, int32 output_extent) -{ - md5_state_t md5; - unsigned char md5_buf[16]; - char *p; - int i; - - /* calculate the MD5 hash of the story file */ - md5_init(&md5); - md5_append(&md5, story_file, extent); - md5_finish(&md5, md5_buf); - - /* make sure we have room to store the result */ - ASSERT_OUTPUT_SIZE(39); - - /* the prefix is "TADS2-" or "TADS3-", depending on the format */ - if (tads_match_sig(story_file, extent, T2_SIGNATURE)) - strcpy(output, "TADS2-"); - else - strcpy(output, "TADS3-"); - - /* the rest is the MD5 hash of the file, as hex digits */ - for (i = 0, p = output + strlen(output) ; i < 16 ; p += 2, ++i) - sprintf(p, "%02X", md5_buf[i]); - - /* indicate that we found one result */ - return 1; -} - -/* ------------------------------------------------------------------------ */ -/* - * Some UTF-8 utility functions and macros. We use our own rather than the - * ctype.h macros because we're parsing UTF-8 text. - */ - -/* is c a space? */ -#define u_isspace(c) ((unsigned char)(c) < 128 && isspace(c)) - -/* is c a horizontal space? */ -#define u_ishspace(c) (u_isspace(c) && (c) != '\n' && (c) != '\r') - -/* is-newline - matches \n, \r, and \u2028 */ -static int u_isnl(const char *p, int32 len) -{ - return (*p == '\n' - || *p == '\r' - || (len >= 3 - && *(unsigned char *)p == 0xe2 - && *(unsigned char *)(p+1) == 0x80 - && *(unsigned char *)(p+2) == 0xa8)); -} - -/* skip to the next utf-8 character */ -static void nextc(const char **p, int32 *len) -{ - /* skip the first byte */ - if (*len != 0) - ++*p, --*len; - - /* skip continuation bytes */ - while (*len != 0 && (**p & 0xC0) == 0x80) - ++*p, --*len; -} - -/* skip to the previous utf-8 character */ -static void prevc(const char **p, int32 *len) -{ - /* move back one byte */ - --*p, ++*len; - - /* keep skipping as long as we're looking at continuation characters */ - while ((**p & 0xC0) == 0x80) - --*p, ++*len; -} - -/* - * Skip a newline sequence. Skips all common conventions, including \n, - * \r, \n\r, \r\n, and \u2028. - */ -static void skip_newline(const char **p, int32 *rem) -{ - /* make sure we have something to skip */ - if (*rem == 0) - return; - - /* check what we have */ - switch (**(const unsigned char **)p) - { - case '\n': - /* skip \n or \n\r */ - nextc(p, rem); - if (**p == '\r') - nextc(p, rem); - break; - - case '\r': - /* skip \r or \r\n */ - nextc(p, rem); - if (**p == '\n') - nextc(p, rem); - break; - - case 0xe2: - /* \u2028 (unicode line separator) - just skip the one character */ - nextc(p, rem); - break; - } -} - -/* - * Skip to the next line - */ -static void skip_to_next_line(const char **p, int32 *rem) -{ - /* look for the next newline */ - for ( ; *rem != 0 ; nextc(p, rem)) - { - /* if this is a newline of some kind, we're at the end of the line */ - if (u_isnl(*p, *rem)) - { - /* skip the newline, and we're done */ - skip_newline(p, rem); - break; - } - } -} - - -/* ------------------------------------------------------------------------ */ -/* - * ifiction synthesizer output context - */ -typedef struct synthctx synthctx; -struct synthctx -{ - /* the current output pointer */ - char *buf; - - /* the number of bytes remaining in the output buffer */ - int32 buf_size; - - /* - * the total number of bytes needed for the output (this might be more - * than we've actually written, since we count up the bytes required - * even if we need more space than the buffer provides) - */ - int32 total_size; - - /* the head of the name/value pair list from the parsed GameInfo */ - valinfo *vals; -}; - -/* initialize a synthesizer context */ -static void init_synthctx(synthctx *ctx, char *buf, int32 bufsize, - valinfo *vals) -{ - /* set up at the beginning of the output buffer */ - ctx->buf = buf; - ctx->buf_size = bufsize; - - /* we haven't written anything to the output buffer yet */ - ctx->total_size = 0; - - /* remember the name/value pair list */ - ctx->vals = vals; -} - -/* - * Write out a chunk to a synthesized ifiction record, updating pointers - * and counters. We won't copy past the end of the buffer, but we'll - * continue counting the output length needed in any case. - */ -static void write_ifiction(synthctx *ctx, const char *src, size_t srclen) -{ - int32 copy_len; - - /* copy as much as we can, up to the remaining buffer size */ - copy_len = srclen; - if (copy_len > ctx->buf_size) - copy_len = ctx->buf_size; - - /* do the copying, if any */ - if (copy_len != 0) - { - /* copy the bytes */ - memcpy(ctx->buf, src, (size_t)copy_len); - - /* adjust the buffer pointer and output buffer size remaining */ - ctx->buf += copy_len; - ctx->buf_size -= copy_len; - } - - /* count this source data in the total size */ - ctx->total_size += srclen; -} - -/* write a null-terminated chunk to the synthesized ifiction record */ -static void write_ifiction_z(synthctx *ctx, const char *src) -{ - write_ifiction(ctx, src, strlen(src)); -} - -/* - * Write a PCDATA string to the synthesized ifiction record. In - * particular, we rewrite '<', '>', and '&' as '<', '>', and '&', - * respectively; we trim off leading and trailing spaces; and we compress - * each run of whitespace down to a single \u0020 (' ') character. - */ -static void write_ifiction_pcdata(synthctx *ctx, const char *p, size_t len) -{ - /* first, skip any leading whitespace */ - for ( ; len != 0 && u_ishspace(*p) ; ++p, --len) ; - - /* keep going until we run out of string */ - for (;;) - { - const char *start; - - /* scan to the next whitespace or markup-significant character */ - for (start = p ; - len != 0 && !u_ishspace(*p) - && *p != '<' && *p != '>' && *p != '&' ; ++p, --len) ; - - /* write the part up to here */ - if (p != start) - write_ifiction(ctx, start, p - start); - - /* if we've reached the end of the string, we can stop */ - if (len == 0) - break; - - /* check what stopped us */ - switch (*p) - { - case '<': - write_ifiction_z(ctx, "<"); - ++p, --len; - break; - - case '>': - write_ifiction_z(ctx, ">"); - ++p, --len; - break; - - case '&': - write_ifiction_z(ctx, "&"); - ++p, --len; - break; - - default: - /* - * The only other thing that could have stopped us is - * whitespace. Skip all consecutive whitespace. - */ - for ( ; len != 0 && u_ishspace(*p) ; ++p, --len); - - /* - * if that's not the end of the string, replace the run of - * whitespace with a single space character in the output; if - * we've reached the end of the string, we don't even want to - * do that, since we want to trim off trailing spaces - */ - if (len != 0) - write_ifiction_z(ctx, " "); - break; - } - } -} - -/* - * Translate a GameInfo keyed value to the corresponding ifiction tagged - * value. We find the GameInfo value keyed by 'gameinfo_key', and write - * out the same string under the ifiction XML tag 'ifiction_tag'. We write - * a complete XML container sequence - value. - * - * If the given GameInfo key doesn't exist, we use the default value string - * 'dflt', if given. If the GameInfo key doesn't exist and 'dflt' is null, - * we don't write anything - we don't even write the open/close tags. - * - * If 'html' is true, we assume the value is in html format, and we write - * it untranslated. Otherwise, we write it as PCDATA, translating markup - * characters into '&' entities and compressing whitespace. - */ -static void write_ifiction_xlat_base(synthctx *ctx, int indent, - const char *gameinfo_key, - const char *ifiction_tag, - const char *dflt, int html) -{ - valinfo *val; - const char *valstr; - size_t vallen; - - /* look up the GameInfo key */ - if ((val = find_by_key(ctx->vals, gameinfo_key)) != 0) - { - /* we found the GameInfo value - use it */ - valstr = val->val; - vallen = val->val_len; - } - else if (dflt != 0) - { - /* the GameInfo value doesn't exist, but we have a default - use it */ - valstr = dflt; - vallen = strlen(dflt); - } - else - { - /* there's no GameInfo value and no default, so write nothing */ - return; - } - - /* write the indentation */ - while (indent != 0) - { - static const char spaces[] = " "; - size_t cur; - - /* figure how much we can write on this round */ - cur = indent; - if (cur > sizeof(spaces) - 1) - cur = sizeof(spaces) - 1; - - /* write it */ - write_ifiction(ctx, spaces, cur); - - /* deduct it from the amount remaining */ - indent -= cur; - } - - /* write the open tag */ - write_ifiction_z(ctx, "<"); - write_ifiction_z(ctx, ifiction_tag); - write_ifiction_z(ctx, ">"); - - /* write the value, applying pcdata translations */ - if (html) - write_ifiction(ctx, valstr, vallen); - else - write_ifiction_pcdata(ctx, valstr, vallen); - - /* write the close tag */ - write_ifiction_z(ctx, "\n"); -} - -#define write_ifiction_xlat(ctx, indent, gikey, iftag, dflt) \ - write_ifiction_xlat_base(ctx, indent, gikey, iftag, dflt, FALSE) - -#define write_ifiction_xlat_html(ctx, indent, gikey, iftag, dflt) \ - write_ifiction_xlat_base(ctx, indent, gikey, iftag, dflt, TRUE) - - -/* - * Retrieve the next author name from the GameInfo "Author" format. The - * format is as follows: - * - * name ... ; ... - * - * That is, each author is listed with a name followed by one or more email - * addresses in angle brackets, and multiple authors are separated by - * semicolons. - */ -static int scan_author_name(const char **p, size_t *len, - const char **start, const char **end) -{ - /* keep going until we find a non-empty author name */ - for (;;) - { - /* skip leading spaces */ - for ( ; *len != 0 && u_ishspace(**p) ; ++*p, --*len) ; - - /* if we ran out of string, there's definitely no author name */ - if (*len == 0) - return FALSE; - - /* - * Find the end of this author name. The author name ends at the - * next semicolon or angle bracket. - */ - for (*start = *p ; *len != 0 && **p != ';' && **p != '<' ; - ++*p, --*len) ; - - /* trim off any trailing spaces */ - for (*end = *p ; *end > *start && u_ishspace(*(*end - 1)) ; --*end) ; - - /* now skip any email addresses */ - while (*len != 0 && **p == '<') - { - /* skip to the closing bracket */ - for (++*p, --*len ; *len != 0 && **p != '>' ; ++*p, --*len) ; - - /* skip the bracket */ - if (*len != 0) - ++*p, --*len; - - /* skip whitespace */ - for ( ; *len != 0 && u_ishspace(**p) ; ++*p, --*len) ; - - /* - * if we're not at a semicolon, another angle bracket, or the - * end of the string, it's a syntax error - */ - if (*len != 0 && **p != '<' && **p != ';') - { - *len = 0; - return FALSE; - } - } - - /* if we're at a semicolon, skip it */ - if (*len != 0 && **p == ';') - ++*p, --*len; - - /* - * if we found a non-empty name, return it; otherwise, continue on - * to the next semicolon section - */ - if (*end != *start) - return TRUE; - } -} - - -/* - * Synthesize an ifiction record for the given GameInfo name/value pair - * list. Returns the number of bytes required for the result, including - * null termination. We'll copy as much as we can to the output buffer, up - * to bufsize; if the buffer size is insufficient to hold the result, we'll - * still indicate the length needed for the full result, but we're careful - * not to actually copy anything past the end of the buffer. - */ -static int32 synth_ifiction(valinfo *vals, int tads_version, - char *buf, int32 bufsize, - void *story_file, int32 extent) -{ - char default_ifid[TREATY_MINIMUM_EXTENT]; - valinfo *ifid = find_by_key(vals, "IFID"); - const char *ifid_val; - size_t ifid_len; - valinfo *author = find_by_key(vals, "AuthorEmail"); - valinfo *url = find_by_key(vals, "Url"); - synthctx ctx; - const char *p; - size_t rem; - int32 art_fmt; - int32 art_wid, art_ht; - - /* initialize the output content */ - init_synthctx(&ctx, buf, bufsize, vals); - - /* make sure the tads version is one we know how to handle */ - if (tads_version != 2 && tads_version != 3) - return NO_REPLY_RV; - - /* - * The IFID is mandatory. If there's not an IFID specifically listed - * in the GameInfo, we need to generate the default IFID based on the - * MD5 hash of the game file. - */ - if (ifid != 0) - { - /* use the explicit IFID(s) listed in the GameInfo */ - ifid_val = ifid->val; - ifid_len = ifid->val_len; - } - else - { - /* generate the default IFID */ - generate_md5_ifid(story_file, extent, - default_ifid, TREATY_MINIMUM_EXTENT); - - /* use this as the IFID */ - ifid_val = default_ifid; - ifid_len = strlen(default_ifid); - } - - /* write the header, and start the section */ - write_ifiction_z( - &ctx, - "\n" - "\n" - " \n" - " \n" - " \n" - " Babel\n" - " " TREATY_VERSION "\n" - " 2006-04-14\n" - " \n" - " \n"); - - /* write each IFID (there might be several) */ - for (p = ifid_val, rem = ifid_len ; rem != 0 ; ) - { - const char *start; - const char *end; - - /* skip leading spaces */ - for ( ; rem != 0 && u_ishspace(*p) ; ++p, --rem) ; - - /* find the end of this IFID */ - for (start = p ; rem != 0 && *p != ',' ; ++p, --rem) ; - - /* remove trailing spaces */ - for (end = p ; end > start && u_ishspace(*(end-1)) ; --end) ; - - /* if we found one, write it out */ - if (end != start) - { - write_ifiction_z(&ctx, " "); - write_ifiction(&ctx, start, end - start); - write_ifiction_z(&ctx, "\n"); - } - - /* skip the comma */ - if (rem != 0 && *p == ',') - ++p, --rem; - } - - /* add the format information */ - write_ifiction_z(&ctx, - tads_version == 2 - ? " tads2\n" - : " tads3\n"); - - /* close the section and start the */ - write_ifiction_z(&ctx, - " \n" - " \n"); - - /* write the various bibliographic data */ - write_ifiction_xlat(&ctx, 6, "Name", "title", "An Interactive Fiction"); - write_ifiction_xlat(&ctx, 6, "Headline", "headline", 0); - write_ifiction_xlat(&ctx, 6, "Desc", "description", 0); - write_ifiction_xlat(&ctx, 6, "Genre", "genre", 0); - write_ifiction_xlat(&ctx, 6, "Forgiveness", "forgiveness", 0); - write_ifiction_xlat(&ctx, 6, "Series", "series", 0); - write_ifiction_xlat(&ctx, 6, "SeriesNumber", "seriesnumber", 0); - write_ifiction_xlat(&ctx, 6, "Language", "language", 0); - write_ifiction_xlat(&ctx, 6, "FirstPublished", "firstpublished", 0); - - /* if there's an author, write the list of author names */ - if (author != 0) - { - int cnt; - int i; - const char *start; - const char *end; - - /* start the tag */ - write_ifiction_z(&ctx, " "); - - /* - * first, count up the number of authors - authors are separated by - * semicolons, so there's one more author than there are semicolons - */ - for (p = author->val, rem = author->val_len, cnt = 1 ; - scan_author_name(&p, &rem, &start, &end) ; ) ; - - /* - * Now generate the list of authors. If there are multiple - * authors, use commas to separate them. - */ - for (p = author->val, rem = author->val_len, i = 0 ; ; ++i) - { - /* scan this author's name */ - if (!scan_author_name(&p, &rem, &start, &end)) - break; - - /* write out this author name */ - write_ifiction_pcdata(&ctx, start, end - start); - - /* if there's another name to come, write a separator */ - if (i + 1 < cnt) - { - /* - * write just "and" to separate two items; write "," - * between items in lists of more than two, with ",and" - * between the last two items - */ - write_ifiction_z(&ctx, - cnt == 2 ? " and " : - i + 2 < cnt ? ", " : ", and "); - } - } - - /* end the tag */ - write_ifiction_z(&ctx, "\n"); - } - - /* end the biblio section */ - write_ifiction_z(&ctx, " \n"); - - /* if there's cover art, add its information */ - if (find_cover_art(story_file, extent, 0, &art_fmt, &art_wid, &art_ht) - && (art_fmt == PNG_COVER_FORMAT || art_fmt == JPEG_COVER_FORMAT)) - { - char buf[200]; - - sprintf(buf, - " \n" - " %s\n" - " %lu\n" - " %lu\n" - " \n", - art_fmt == PNG_COVER_FORMAT ? "png" : "jpg", - (long)art_ht, (long)art_wid); - - write_ifiction_z(&ctx, buf); - } - - /* if there's an author email, include it */ - if (author != 0 || url != 0) - { - const char *p; - size_t rem; - int i; - - /* open the section */ - write_ifiction_z(&ctx, " \n"); - - /* add the author email, if provided */ - if (author != 0) - { - /* write the email list */ - for (i = 0, p = author->val, rem = author->val_len ; ; ++i) - { - const char *start; - - /* skip to the next email address */ - for ( ; rem != 0 && *p != '<' ; ++p, --rem) ; - - /* if we didn't find an email address, we're done */ - if (rem == 0) - break; - - /* find the matching '>' */ - for (++p, --rem, start = p ; rem != 0 && *p != '>' ; - ++p, --rem) ; - - /* - * if this is the first one, open the section; otherwise, - * add a comma - */ - if (i == 0) - write_ifiction_z(&ctx, " "); - else - write_ifiction_z(&ctx, ","); - - /* write this address */ - write_ifiction(&ctx, start, p - start); - - /* - * skip the closing bracket, if there is one; if we're out - * of string, we're done - */ - if (rem != 0) - ++p, --rem; - else - break; - } - - /* if we found any emails to write, end the section */ - if (i != 0) - write_ifiction_z(&ctx, "\n"); - } - - /* if there's a URL, add it */ - if (url != 0) - { - write_ifiction_z(&ctx, " "); - write_ifiction(&ctx, url->val, url->val_len); - write_ifiction_z(&ctx, "\n"); - } - - /* close the section */ - write_ifiction_z(&ctx, " \n"); - } - - /* add the tads-specific section */ - write_ifiction_z(&ctx, " \n"); - - write_ifiction_xlat(&ctx, 6, "Version", "version", 0); - write_ifiction_xlat(&ctx, 6, "ReleaseDate", "releasedate", 0); - write_ifiction_xlat(&ctx, 6, "PresentationProfile", - "presentationprofile", 0); - write_ifiction_xlat(&ctx, 6, "Byline", "byline", 0); - - write_ifiction_z(&ctx, " \n"); - - /* close the story section and the main body */ - write_ifiction_z(&ctx, " \n\n"); - - /* add the null terminator */ - write_ifiction(&ctx, "", 1); - - /* return the total output size */ - return ctx.total_size; -} - -/* ------------------------------------------------------------------------ */ -/* - * Check a data block to see if it starts with the given signature. - */ -int tads_match_sig(const void *buf, int32 len, const char *sig) -{ - /* note the length of the signature string */ - size_t sig_len = strlen(sig); - - /* if matches if the buffer starts with the signature string */ - return (len >= (int32)sig_len && memcmp(buf, sig, sig_len) == 0); -} - - -/* ------------------------------------------------------------------------ */ -/* - * portable-to-native format conversions - */ -#define osbyte(p, ofs) \ - (*(((unsigned char *)(p)) + (ofs))) - -#define osrp1(p) \ - ((unsigned int)osbyte(p, 0)) - -#define osrp2(p) \ - ((unsigned int)osbyte(p, 0) \ - + ((unsigned int)osbyte(p, 1) << 8)) - -#define osrp4(p) \ - (((unsigned long)osbyte(p, 0)) \ - + (((unsigned long)osbyte(p, 1)) << 8) \ - + (((unsigned long)osbyte(p, 2)) << 16) \ - + (((unsigned long)osbyte(p, 3)) << 24)) - - -/* ------------------------------------------------------------------------ */ -/* - * Parse a game file and retrieve the GameInfo data. Returns the head of a - * linked list of valinfo entries. - */ -static valinfo *parse_game_info(const void *story_file, int32 story_len, - int *tads_version) -{ - resinfo res; - const char *p; - int32 rem; - valinfo *val_head = 0; - - /* - * first, find the GameInfo resource - if it's not there, there's no - * game information to parse - */ - if (!find_resource(story_file, story_len, "GameInfo.txt", &res)) - return 0; - - /* if the caller wants the TADS version number, hand it back */ - if (tads_version != 0) - *tads_version = res.tads_version; - - /* parse the data */ - for (p = res.ptr, rem = res.len ; rem != 0 ; ) - { - const char *name_start; - size_t name_len; - const char *val_start; - valinfo *val; - const char *inp; - int32 inlen; - char *outp; - - /* skip any leading whitespace */ - while (rem != 0 && u_isspace(*p)) - ++p, --rem; - - /* if the line starts with '#', it's a comment, so skip it */ - if (rem != 0 && *p == '#') - { - skip_to_next_line(&p, &rem); - continue; - } - - /* we must have the start of a name - note it */ - name_start = p; - - /* skip ahead to a space or colon */ - while (rem != 0 && *p != ':' && !u_ishspace(*p)) - nextc(&p, &rem); - - /* note the length of the name */ - name_len = p - name_start; - - /* skip any whitespace before the presumed colon */ - while (rem != 0 && u_ishspace(*p)) - nextc(&p, &rem); - - /* if we're not at a colon, the line is ill-formed, so skip it */ - if (rem == 0 || *p != ':') - { - /* skip the entire line, and go back for the next one */ - skip_to_next_line(&p, &rem); - continue; - } - - /* skip the colon and any whitespace immediately after it */ - for (nextc(&p, &rem) ; rem != 0 && u_ishspace(*p) ; nextc(&p, &rem)) ; - - /* note where the value starts */ - val_start = p; - - /* - * Scan the value to get its length. The value runs from here to - * the next newline that's not followed immediately by a space. - */ - while (rem != 0) - { - const char *nl; - int32 nlrem; - - /* skip to the next line */ - skip_to_next_line(&p, &rem); - - /* if we're at eof, we can stop now */ - if (rem == 0) - break; - - /* note where this line starts */ - nl = p; - nlrem = rem; - - /* - * if we're at a non-whitespace character, it's definitely not - * a continuation line - */ - if (!u_ishspace(*p)) - break; - - /* - * check for spaces followed by a non-space character - this - * would signify a continuation line - */ - for ( ; rem != 0 && u_ishspace(*p) ; nextc(&p, &rem)) ; - if (rem == 0 || u_isnl(p, rem)) - { - /* - * we're at end of file, we found a line with nothing but - * whitespace, so this isn't a continuation line; go back - * to the start of this line and end the value here - */ - p = nl; - rem = nlrem; - break; - } - - /* - * We found whitespace followed by non-whitespace, so this is a - * continuation line. Keep going for now. - */ - } - - /* remove any trailing newlines */ - while (p > val_start) - { - /* move back one character */ - prevc(&p, &rem); - - /* - * if it's a newline, keep going; otherwise, keep this - * character and stop trimming - */ - if (!u_isnl(p, rem)) - { - nextc(&p, &rem); - break; - } - } - - /* - * Allocate a new value entry. Make room for the entry itself plus - * a copy of the value. We don't need to make a copy of the name, - * since we can just use the original copy from the story file - * buffer. We do need a copy of the value because we might need to - * transform it slightly, to remove newlines and leading spaces on - * continuation lines. - */ - val = (valinfo *)malloc(sizeof(valinfo) + (p - val_start)); - - /* link it into our list */ - val->nxt = val_head; - val_head = val; - - /* point the name directly to the name in the buffer */ - val->name = name_start; - val->name_len = name_len; - - /* point the value to the space allocated along with the valinfo */ - val->val = (char *)(val + 1); - - /* store the name, removing newlines and continuation-line spaces */ - for (outp = val->val, inp = val_start, inlen = p - val_start ; - inlen != 0 ; ) - { - const char *l; - - /* find the next newline */ - for (l = inp ; inlen != 0 && !u_isnl(inp, inlen) ; - nextc(&inp, &inlen)) ; - - /* copy this line to the output */ - memcpy(outp, l, inp - l); - outp += inp - l; - - /* if we're out of input, we're done */ - if (inlen == 0) - break; - - /* we're at a newline: replace it with a space in the output */ - *outp++ = ' '; - - /* skip the newline and subsequent whitespace in the input */ - for (skip_newline(&inp, &inlen) ; - inlen != 0 && u_ishspace(*inp) ; nextc(&inp, &inlen)) ; - } - - /* set the length of the parsed value */ - val->val_len = outp - val->val; - - /* skip to the next line and continue parsing */ - skip_to_next_line(&p, &rem); - } - - /* return the head of the linked list of value entries */ - return val_head; -} -static int my_memicmp(const void *aa, const void *bb, int l) -{ - int s=0,i; - char *a=(char *) aa; - char *b=(char *) bb; - for(i=0;inxt) - { - /* if this one matches the key we're looking for, return it */ - if (p->name_len == key_len && my_memicmp(p->name, key, key_len) == 0) - return p; - } - - /* no luck */ - return 0; -} - -/* ------------------------------------------------------------------------ */ -/* - * Delete a valinfo list obtained from parse_game_info() - */ -static void delete_valinfo_list(valinfo *head) -{ - /* keep going until we run out of entries */ - while (head != 0) - { - /* remember the next entry, before we delete this one */ - valinfo *nxt = head->nxt; - - /* delete this one */ - free(head); - - /* move on to the next one */ - head = nxt; - } -} - -/* ------------------------------------------------------------------------ */ -/* - * Find the cover art resource. We'll look for CoverArt.jpg and - * CoverArt.png, in that order. - */ -static int find_cover_art(const void *story_file, int32 story_len, - resinfo *resp, int32 *image_format, - int32 *width, int32 *height) -{ - resinfo res; - int32 x, y; - - /* if they didn't want the resource info, provide a placeholder */ - if (resp == 0) - resp = &res; - - /* look for CoverArt.jpg first */ - if (find_resource(story_file, story_len, "CoverArt.jpg", resp)) - { - /* get the width and height */ - if (!get_jpeg_dim(resp->ptr, resp->len, &x, &y)) - return FALSE; - - /* hand back the width and height if it was requested */ - if (width != 0) - *width = x; - if (height != 0) - *height = y; - - /* tell them it's a JPEG image */ - if (image_format != 0) - *image_format = JPEG_COVER_FORMAT; - - /* indicate success */ - return TRUE; - } - - /* look for CoverArt.png second */ - if (find_resource(story_file, story_len, "CoverArt.png", resp)) - { - /* get the width and height */ - if (!get_png_dim(resp->ptr, resp->len, &x, &y)) - return FALSE; - - /* hand back the width and height if it was requested */ - if (width != 0) - *width = x; - if (height != 0) - *height = y; - - /* tell them it's a PNG image */ - if (image_format != 0) - *image_format = PNG_COVER_FORMAT; - - /* indicate success */ - return TRUE; - } - - /* didn't find it */ - return FALSE; -} - -/* ------------------------------------------------------------------------ */ -/* - * Find a resource in a TADS 2 or 3 story file that's been loaded into - * memory. On success, fills in the offset and size of the resource and - * returns TRUE; if the resource isn't found, returns FALSE. - */ -static int find_resource(const void *story_file, int32 story_len, - const char *resname, resinfo *info) -{ - /* if there's no file, there's no resource */ - if (story_file == 0) - return FALSE; - - /* check for tads 2 */ - if (tads_match_sig(story_file, story_len, T2_SIGNATURE)) - { - info->tads_version = 2; - return t2_find_res(story_file, story_len, resname, info); - } - - /* check for tads 3 */ - if (tads_match_sig(story_file, story_len, T3_SIGNATURE)) - { - info->tads_version = 3; - return t3_find_res(story_file, story_len, resname, info); - } - - /* it's not one of ours */ - return FALSE; -} - -/* ------------------------------------------------------------------------ */ -/* - * Find a resource in a tads 2 game file - */ -static int t2_find_res(const void *story_file, int32 story_len, - const char *resname, resinfo *info) -{ - const char *basep = (const char *)story_file; - const char *endp = basep + story_len; - const char *p; - size_t resname_len; - - /* note the length of the name we're seeking */ - resname_len = strlen(resname); - - /* - * skip past the tads 2 file header (13 bytes for the signature, 7 - * bytes for the version header, 2 bytes for the flags, 26 bytes for - * the timestamp) - */ - p = basep + 13 + 7 + 2 + 26; - - /* - * scan the sections in the file; stop on $EOF, and skip everything - * else but HTMLRES, which is the section type that - */ - while (p < endp) - { - unsigned long endofs; - - /* - * We're pointing to a section block header, which looks like this: - * - *. type-length - *. type-name - *. next-section-address - */ - - /* read the ending offset */ - endofs = osrp4(p + 1 + osrp1(p)); - - /* check the type */ - if (p[0] == 7 && memcmp(p + 1, "HTMLRES", 7) == 0) - { - unsigned long found_ofs; - int found; - unsigned long entry_cnt; - - /* we haven't found the resource yet */ - found = FALSE; - - /* - * It's a multimedia resource block. Skip the section block - * header and look at the index table - the index table - * consists of a uint32 giving the number of entries, followed - * by a reserved uint32, followed by the entries. - */ - p += 12; - entry_cnt = osrp4(p); - - /* skip to the first index entry */ - p += 8; - - /* scan the index entries */ - for ( ; entry_cnt != 0 ; --entry_cnt) - { - unsigned long res_ofs; - unsigned long res_siz; - size_t name_len; - - /* - * We're at the next index entry, which looks like this: - * - *. resource-address (bytes from end of index) - *. resource-length (in bytes) - *. name-length - *. name - */ - res_ofs = osrp4(p); - res_siz = osrp4(p + 4); - name_len = osrp2(p + 8); - p += 10; - - /* check for a match to the name we're looking for */ - if (name_len == resname_len - && my_memicmp(resname, p, name_len) == 0) - { - /* - * it's the one we want - note its resource location - * and size, but keep scanning for now, since we need - * to find the end of the index before we'll know where - * the actual resources begin - */ - found = TRUE; - found_ofs = res_ofs; - info->len = res_siz; - } - - /* skip this one's name */ - p += name_len; - } - - /* - * if we found our resource, the current seek position is the - * base of the offset we found in the directory; so we can - * finally fix up the offset to give the actual file location - * and return the result - */ - if (found) - { - /* fix up the offset with the actual file location */ - info->ptr = p + found_ofs; - - /* tell the caller we found it */ - return TRUE; - } - } - else if (p[0] == 4 && memcmp(p + 1, "$EOF", 4) == 0) - { - /* - * that's the end of the file - we've finished without finding - * the resource, so return failure - */ - return FALSE; - } - - /* move to the next section */ - p = basep + endofs; - } - - /* - * reached EOF without an $EOF marker - file must be corrupted; return - * 'not found' - */ - return FALSE; -} - -/* ------------------------------------------------------------------------ */ -/* - * Find a resource in a T3 image file - */ -static int t3_find_res(const void *story_file, int32 story_len, - const char *resname, resinfo *info) -{ - const char *basep = (const char *)story_file; - const char *endp = basep + story_len; - const char *p; - size_t resname_len; - - /* note the length of the name we're seeking */ - resname_len = strlen(resname); - - /* - * skip the file header - 11 bytes for the signature, 2 bytes for the - * format version, 32 reserved bytes, and 24 bytes for the timestamp - */ - p = basep + 11 + 2 + 32 + 24; - - /* scan the data blocks */ - while (p < endp) - { - unsigned long siz; - - /* - * We're at the next block header, which looks like this: - * - *. type-name - *. block-size - *. flags - */ - - /* get the block size */ - siz = osrp4(p + 4); - - /* check the type */ - if (memcmp(p, "MRES", 4) == 0) - { - unsigned int entry_cnt; - unsigned int i; - const char *blockp; - - /* skip the header */ - p += 10; - - /* - * remember the location of the base of the block - the data - * seek location for each index entry is given as an offset - * from this location - */ - blockp = p; - - /* the first thing in the table is the number of entries */ - entry_cnt = osrp2(p); - p += 2; - - /* read the entries */ - for (i = 0 ; i < entry_cnt ; ++i) - { - unsigned long entry_ofs; - unsigned long entry_siz; - size_t entry_name_len; - char namebuf[256]; - char *xp; - size_t xi; - - /* - * Parse this index entry: - * - *. address (as offset from the block base) - *. size (in bytes) - *. name-length - *. name (all bytes XORed with 0xFF) - */ - entry_ofs = osrp4(p); - entry_siz = osrp4(p + 4); - entry_name_len = (unsigned char)p[8]; - - /* unmask the name */ - memcpy(namebuf, p + 9, resname_len); - for (xi = resname_len, xp = namebuf ; xi != 0 ; --xi) - *xp++ ^= 0xFF; - - /* if this is the one we're looking for, return it */ - if (entry_name_len == resname_len - && my_memicmp(resname, namebuf, resname_len) == 0) - { - /* - * fill in the return information - note that the entry - * offset given in the header is an offset from data - * block's starting location, so fix this up to an - * absolute seek location for the return value - */ - info->ptr = blockp + entry_ofs; - info->len = entry_siz; - - /* return success */ - return TRUE; - } - - /* skip this entry (header + name length) */ - p += 9 + entry_name_len; - } - - /* - * if we got this far, we didn't find the name; so skip past - * the MRES section by adding the section length to the base - * pointer, and resume the main file scan - */ - p = blockp + siz; - } - else if (memcmp(p, "EOF ", 4) == 0) - { - /* - * end of file - we've finished without finding the resource, - * so return failure - */ - return FALSE; - } - else - { - /* - * we don't care about anything else - just skip this block and - * keep going; to skip the block, simply seek ahead past the - * block header and then past the block's contents, using the - * size given the in block header - */ - p += siz + 10; - } - } - - /* - * reached EOF without an EOF marker - file must be corrupted; return - * 'not found' - */ - return FALSE; -} - -/* ------------------------------------------------------------------------ */ -/* - * JPEG and PNG information extraction (based on the versions in - * babel_story_functions.c) - */ -static int get_jpeg_dim(const void *img, int32 extent, - int32 *xout, int32 *yout) -{ - const unsigned char *dp=(const unsigned char *) img; - const unsigned char *ep=dp+extent; - unsigned int t1, t2, w, h; - - t1 = *dp++; - t2 = *dp++; - if (t1 != 0xff || t2 != 0xD8) - return FALSE; - - while(1) - { - if (dp>ep) return FALSE; - for(t1=*(dp++);t1!=0xff;t1=*(dp++)) if (dp>ep) return FALSE; - do { t1=*(dp++); if (dp>ep) return FALSE;} while (t1 == 0xff); - - if ((t1 & 0xF0) == 0xC0 && !(t1==0xC4 || t1==0xC8 || t1==0xCC)) - { - dp+=3; - if (dp>ep) return FALSE; - h=*(dp++) << 8; - if (dp>ep) return FALSE; - h|=*(dp++); - if (dp>ep) return FALSE; - w=*(dp++) << 8; - if (dp>ep) return FALSE; - w|=*(dp); - - *xout = w; - *yout = h; - return TRUE; - } - else if (t1==0xD8 || t1==0xD9) - break; - else - { - int l; - - if (dp>ep) return FALSE; - l=*(dp++) << 8; - if (dp>ep) return FALSE; - l|= *(dp++); - l-=2; - dp+=l; - if (dp>ep) return FALSE; - } - } - return FALSE; -} - -static int32 png_read_int(const unsigned char *mem) -{ - int32 i4 = mem[0], - i3 = mem[1], - i2 = mem[2], - i1 = mem[3]; - return i1 | (i2<<8) | (i3<<16) | (i4<<24); -} - - -static int get_png_dim(const void *img, int32 extent, - int32 *xout, int32 *yout) -{ - const unsigned char *dp=(const unsigned char *)img; - - if (extent<33 || - !(dp[0]==137 && dp[1]==80 && dp[2]==78 && dp[3]==71 && - dp[4]==13 && dp[5] == 10 && dp[6] == 26 && dp[7]==10)|| - !(dp[12]=='I' && dp[13]=='H' && dp[14]=='D' && dp[15]=='R')) - return FALSE; - - *xout = png_read_int(dp+16); - *yout = png_read_int(dp+20); - return TRUE; -} - -/* ------------------------------------------------------------------------ */ -/* - * Testing main() - this implements a set of unit tests on the tads - * version. - */ - -#ifdef TADS_TEST - -#include "babel_handler.h" - -void main(int argc, char **argv) -{ - FILE *fp; - int32 siz; - void *buf; - valinfo *head; - int32 rv; - int tadsver; - char outbuf[TREATY_MINIMUM_EXTENT]; - - /* check arguments */ - if (argc != 2) - { - printf("usage: tads \n"); - exit(1); - } - - /* initialize the babel subsystems */ - babel_init(argv[1]); - - /* open the story file */ - if ((fp = fopen(argv[1], "rb")) == 0) - { - printf("error opening input file\n"); - exit(2); - } - - /* check the file size */ - fseek(fp, 0, SEEK_END); - siz = ftell(fp); - fseek(fp, 0, SEEK_SET); - - /* allocate space for it */ - if ((buf = malloc(siz)) == 0) - { - printf("error allocating space to load file\n"); - exit(2); - } - - /* load it */ - if ((int32)fread(buf, 1, siz, fp) != siz) - { - printf("error reading file\n"); - exit(2); - } - - /* done with the file */ - fclose(fp); - - - - /* ===== test 1 - basic parse_game_info() test ===== */ - - /* parse the gameinfo record and print the results */ - if ((head = parse_game_info(buf, siz, &tadsver)) != 0) - { - valinfo *val; - - printf("found GameInfo - tads major version = %d\n", tadsver); - for (val = head ; val != 0 ; val = val->nxt) - { - printf("%.*s=[%.*s]\n", - (int)val->name_len, val->name, - (int)val->val_len, val->val); - } - printf("\n"); - } - else - printf("no GameInfo found\n\n"); - - - - /* ===== test 2 - test the get_story_file_IFID generator ===== */ - rv = tads_get_story_file_IFID(buf, siz, outbuf, TREATY_MINIMUM_EXTENT); - if (rv == 1) - printf("IFID = [%s]\n\n", outbuf); - else - printf("IFID return code = %ld\n", rv); - - - - /* ===== test 3 - test the ifiction synthesizer ===== */ - if ((rv = tads_get_story_file_metadata_extent(buf, siz)) > 0) - { - char *ifbuf; - - /* try allocating the space */ - if ((ifbuf = malloc((size_t)rv)) != 0) - { - /* synthesize the story file */ - rv = tads_get_story_file_metadata(buf, siz, ifbuf, rv); - if (rv > 0) - printf("ifiction metadata:\n=====\n%.*s\n=====\n\n", - (int)rv, ifbuf); - else - printf("tads_get_story_file_metadata result = %ld\n", rv); - } - else - printf("unable to allocate %ld bytes for metadata record\n", rv); - } - else - printf("tads_get_story_file_metadata_extent result code = %ld\n", rv); - - - /* free the loaded story file buffer */ - free(buf); -} - - -#endif TADS_TEST - diff --git a/babel/tads.h b/babel/tads.h deleted file mode 100644 index 296b91d..0000000 --- a/babel/tads.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * tads.h - Treaty of Babel common declarations for tads2 and tads3 modules - * - * This file depends on treaty_builder.h - * - * This file is public domain, but note that any changes to this file may - * render it noncompliant with the Treaty of Babel - * - * Modified - *. 04/18/2006 MJRoberts - creation - */ - -#ifndef TADS_H -#define TADS_H - -/* match a TADS file signature */ -int tads_match_sig(const void *buf, int32 len, const char *sig); - -/* get the IFID for a tads story file */ -int32 tads_get_story_file_IFID(void *story_file, int32 extent, - char *output, int32 output_extent); - -/* get the synthesized iFiction record from a tads story file */ -int32 tads_get_story_file_metadata(void *story_file, int32 extent, - char *buf, int32 bufsize); - -/* get the size of the synthesized iFiction record for a tads story file */ -int32 tads_get_story_file_metadata_extent(void *story_file, int32 extent); - -/* get the cover art from a tads story file */ -int32 tads_get_story_file_cover(void *story_file, int32 extent, - void *buf, int32 bufsize); - -/* get the size of the cover art from a tads story file */ -int32 tads_get_story_file_cover_extent(void *story_file, int32 extent); - -/* get the image format (jpeg, png) of the covert art in a tads story file */ -int32 tads_get_story_file_cover_format(void *story_file, int32 extent); - -#endif /* TADS_H */ diff --git a/babel/tads2.c b/babel/tads2.c deleted file mode 100644 index 87c1fcc..0000000 --- a/babel/tads2.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * tads2.c - Treaty of Babel module for Tads 2 files - * - * This file depends on treaty_builder.h - * - * This file is public domain, but note that any changes to this file may - * render it noncompliant with the Treaty of Babel - * - * Modified - *. 04/15/2006 LRRaszewski - Separated tads2.c and tads3.c - *. 04/08/2006 LRRaszewski - changed babel API calls to threadsafe versions - *. 04/08/2006 MJRoberts - initial implementation - */ - -#define FORMAT tads2 -#define HOME_PAGE "http://www.tads.org" -#define FORMAT_EXT ".gam" - - -#include "treaty_builder.h" -#include "tads.h" - -#define T2_SIGNATURE "TADS2 bin\012\015\032" - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -/* - * get a story file's IFID - */ -static int32 get_story_file_IFID(void *story_file, int32 extent, - char *output, int32 output_extent) -{ - /* use the common tads IFID extractor/generator */ - return tads_get_story_file_IFID(story_file, extent, - output, output_extent); -} - -/* - * determine if a given story file is one of ours - */ -static int32 claim_story_file(void *story_file, int32 extent) -{ - /* check our signature */ - if (tads_match_sig(story_file, extent, T2_SIGNATURE)) - return VALID_STORY_FILE_RV; - - /* not one of ours */ - return INVALID_STORY_FILE_RV; -} - -/* - * Get the size of the iFiction metadata for the game - */ -static int32 get_story_file_metadata_extent(void *story_file, int32 extent) -{ - /* use the common tads iFiction synthesizer */ - return tads_get_story_file_metadata_extent(story_file, extent); -} - -/* - * Get the iFiction metadata for the game - */ -static int32 get_story_file_metadata(void *story_file, int32 extent, - char *buf, int32 bufsize) -{ - /* use the common tads iFiction synthesizer */ - return tads_get_story_file_metadata(story_file, extent, buf, bufsize); -} - -static int32 get_story_file_cover_extent(void *story_file, int32 story_len) -{ - /* use the common tads cover file extractor */ - return tads_get_story_file_cover_extent(story_file, story_len); -} - -/* - * Get the format of the cover art - */ -static int32 get_story_file_cover_format(void *story_file, int32 story_len) -{ - /* use the common tads cover file extractor */ - return tads_get_story_file_cover_format(story_file, story_len); -} - -/* - * Get the cover art data - */ -static int32 get_story_file_cover(void *story_file, int32 story_len, - void *outbuf, int32 output_extent) -{ - /* use the common tads cover file extractor */ - return tads_get_story_file_cover(story_file, story_len, - outbuf, output_extent); -} - diff --git a/babel/tads3.c b/babel/tads3.c deleted file mode 100644 index 23d8fb5..0000000 --- a/babel/tads3.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * tads3.c - Treaty of Babel module for Tads 3 files - * - * This file depends on treaty_builder.h - * - * This file is public domain, but note that any changes to this file may - * render it noncompliant with the Treaty of Babel - * - * Modified - *. 04/15/2006 LRRaszewski - Separated tads2.c and tads3.c - *. 04/08/2006 LRRaszewski - changed babel API calls to threadsafe versions - *. 04/08/2006 MJRoberts - initial implementation - */ - -#define FORMAT tads3 -#define HOME_PAGE "http://www.tads.org" -#define FORMAT_EXT ".t3" - - -#include "treaty_builder.h" -#include "tads.h" - -#define T3_SIGNATURE "T3-image\015\012\032" - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -/* - * get a story file's IFID - */ -static int32 get_story_file_IFID(void *story_file, int32 extent, - char *output, int32 output_extent) -{ - /* use the common tads IFID extractor/generator */ - return tads_get_story_file_IFID(story_file, extent, - output, output_extent); -} - -/* - * determine if a given story file is one of ours - */ -static int32 claim_story_file(void *story_file, int32 extent) -{ - /* check our signature */ - if (tads_match_sig(story_file, extent, T3_SIGNATURE)) - return VALID_STORY_FILE_RV; - - /* not one of ours */ - return INVALID_STORY_FILE_RV; -} - -/* - * Get the size of the iFiction metadata for the game - */ -static int32 get_story_file_metadata_extent(void *story_file, int32 extent) -{ - /* use the common tads iFiction synthesizer */ - return tads_get_story_file_metadata_extent(story_file, extent); -} - -/* - * Get the iFiction metadata for the game - */ -static int32 get_story_file_metadata(void *story_file, int32 extent, - char *buf, int32 bufsize) -{ - /* use the common tads iFiction synthesizer */ - return tads_get_story_file_metadata(story_file, extent, buf, bufsize); -} - -static int32 get_story_file_cover_extent(void *story_file, int32 story_len) -{ - /* use the common tads cover file extractor */ - return tads_get_story_file_cover_extent(story_file, story_len); -} - -/* - * Get the format of the cover art - */ -static int32 get_story_file_cover_format(void *story_file, int32 story_len) -{ - /* use the common tads cover file extractor */ - return tads_get_story_file_cover_format(story_file, story_len); -} - -/* - * Get the cover art data - */ -static int32 get_story_file_cover(void *story_file, int32 story_len, - void *outbuf, int32 output_extent) -{ - /* use the common tads cover file extractor */ - return tads_get_story_file_cover(story_file, story_len, - outbuf, output_extent); -} - diff --git a/babel/treaty.h b/babel/treaty.h deleted file mode 100644 index 7155553..0000000 --- a/babel/treaty.h +++ /dev/null @@ -1,91 +0,0 @@ -/* treaty.h Header file for Treaty of Babel compliant format modules - * By L. Ross Raszewski - * Version 3b - * - * This file is public domain, but please note that derived versions - * may not not be compliant with the Treaty of Babel. - * - * It would be wise for derived works to change the value of - * TREATY_COMPLIANCE to reflect deviations - */ - -#ifndef TREATY_H - -#define TREATY_H - -#define TREATY_COMPLIANCE "Treaty of Babel revision 7" -#define TREATY_VERSION "r7" - -/* return codes */ -#define NO_REPLY_RV 0 -#define INVALID_STORY_FILE_RV -1 -#define UNAVAILABLE_RV -2 -#define INVALID_USAGE_RV -3 -#define INCOMPLETE_REPLY_RV -4 -#define VALID_STORY_FILE_RV 1 - -#define PNG_COVER_FORMAT 1 -#define JPEG_COVER_FORMAT 2 - -/* Treaty bitmasks. These are not required by the treaty, but are here - as a convenience. -*/ -#define TREATY_SELECTOR_INPUT 0x100 -#define TREATY_SELECTOR_OUTPUT 0x200 -#define TREATY_SELECTOR_NUMBER 0xFF - -#define TREATY_CONTAINER_SELECTOR 0x400 - -/* Treaty selectors */ -#define GET_HOME_PAGE_SEL 0x201 -#define GET_FORMAT_NAME_SEL 0x202 -#define GET_FILE_EXTENSIONS_SEL 0x203 -#define CLAIM_STORY_FILE_SEL 0x104 -#define GET_STORY_FILE_METADATA_EXTENT_SEL 0x105 -#define GET_STORY_FILE_COVER_EXTENT_SEL 0x106 -#define GET_STORY_FILE_COVER_FORMAT_SEL 0x107 -#define GET_STORY_FILE_IFID_SEL 0x308 -#define GET_STORY_FILE_METADATA_SEL 0x309 -#define GET_STORY_FILE_COVER_SEL 0x30A -#define GET_STORY_FILE_EXTENSION_SEL 0x30B - -/* Container selectors */ -#define CONTAINER_GET_STORY_FORMAT_SEL 0x710 -#define CONTAINER_GET_STORY_EXTENT_SEL 0x511 -#define CONTAINER_GET_STORY_FILE_SEL 0x711 - - - - -/* Other magic size limits */ -#define TREATY_MINIMUM_EXTENT 512 - - -#include - -/* 32-bit integer types */ -#ifndef VAX -#if SCHAR_MAX >= 0x7FFFFFFFL && SCHAR_MIN <= -0x7FFFFFFFL - typedef signed char int32; -#elif SHRT_MAX >= 0x7FFFFFFFL && SHRT_MIN <= -0x7FFFFFFFL - typedef signed short int int32; -#elif INT_MAX >= 0x7FFFFFFFL && INT_MIN <= -0x7FFFFFFFL - typedef signed int int32; -#elif LONG_MAX >= 0x7FFFFFFFL && LONG_MIN <= -0x7FFFFFFFL - typedef signed long int int32; -#else -#error No type large enough to support 32-bit integers. -#endif -#else - /* VAX C does not provide these limit constants, contrary to ANSI */ - typedef int int32; -#endif - - - -/* Pointer to treaty function. Treaty functions must follow this prototype */ - -typedef int32 (*TREATY)(int32 selector, void *, int32, void *, int32); - -#endif - diff --git a/babel/treaty_builder.h b/babel/treaty_builder.h deleted file mode 100644 index d52ae3e..0000000 --- a/babel/treaty_builder.h +++ /dev/null @@ -1,180 +0,0 @@ -/* treaty_builder.h common macros to build a treaty module - * - * 2006 By L. Ross Raszewski - * - * This file is public domain, but be aware that any changes to it may - * cause it to cease to be compliant with the Treaty of Babel. - * - * This file depends on treaty.h - * - * The purpose of this file is to simplify the building of a treaty - * module. It automatically generates a generic treaty function. - * - * Usage: - * - * #define the following values: - * FORMAT The treaty name of the format - * HOME_PAGE A string containing the URL of the format home page - * FORMAT_EXT A string containing a comma separated list of common - * extensions for game files in this format - * NO_METADATA If the format does not support metadata - * NO_COVER If the format does not support cover art - * CUSTOM_EXTENSION If game files should not always use the first listed extension - * - * (Note: Formats which support metadata and cover art via a container should - * define NO_METADATA and NO_COVER as container support is handled separately) - * - * #include "treaty_builder.h" - * Define the following functions: - * static int32 get_story_file_IFID(void *, int32, char *, int32); - * static int32 claim_story_file(void *, int32); - * Define the following functions if NO_METADATA is not defined: - * static int32 get_story_file_metadata_extent(void *, int32); - * static int32 get_story_file_metadata(void *, int32, char *, int32); - * Define the following functions if NO_COVER is not defined - * static int32 get_story_file_cover_extent(void *, int32); - * static int32 get_story_file_cover_format(void *, int32); - * static int32 get_story_file_cover(void *, int32, void *, int32); - * Define the following if CUSTOM_EXTENSION is defined - * static int32 get_story_file_extension(void *, int32, char *, int32); - * - * The two-parameter functions take the story file and story file extent - * as parameters. The four-parameter ones also take the output - * buffer and its extent. They perform the corresponding task to the - * similarly-named selector. - * - * This file also defines the macro ASSERT_OUTPUT_SIZE(x) which - * returns INVALID_USAGE_RV if output_extent is less than x. - * - * #define CONTAINER_FORMAT before inclusion to generate a container - * module. A container module should define three additional functions: - * static int32 get_story_format(void *, int32, char *, int32); - * static int32 get_story_extent(void *, int32); - * static int32 get_story_file(void *, int32, void *, int32); - * - */ - -#ifndef TREATY_BUILDER -#define TREATY_BUILDER - -#include "treaty.h" -#include - -#define ASSERT_OUTPUT_SIZE(x) do { if (output_extent < (x)) return INVALID_USAGE_RV; } while (0) - -#ifndef NO_METADATA -static int32 get_story_file_metadata_extent(void *, int32); -static int32 get_story_file_metadata(void *, int32, char *, int32); -#endif -#ifndef NO_COVER -static int32 get_story_file_cover_extent(void *, int32); -static int32 get_story_file_cover_format(void *, int32); -static int32 get_story_file_cover(void *, int32, void *, int32); -#endif -static int32 get_story_file_IFID(void *, int32, char *, int32); -static int32 claim_story_file(void *, int32); -#ifdef CONTAINER_FORMAT -static int32 get_story_file(void *, int32, void *, int32); -static int32 get_story_format(void *, int32, char *, int32); -static int32 get_story_extent(void *, int32); -#endif -#ifdef CUSTOM_EXTENSION -static int32 get_story_file_extension(void *, int32, char *, int32); -#else -#include -static int32 get_story_file_extension(void *sf, int32 extent, char *out, int32 output_extent) -{ - int i; - - if (!sf || !extent) return INVALID_STORY_FILE_RV; - - for(i=0;FORMAT_EXT[i] && FORMAT_EXT[i]!=',';i++); - ASSERT_OUTPUT_SIZE(i+1); - memcpy(out,FORMAT_EXT,i); - out[i]=0; - return strlen(out); -} - -#endif - -#define TREATY_FUNCTION(X) DEEP_TREATY_FUNCTION(X) -#define DEEP_TREATY_FUNCTION(X) X ## _treaty -#define dSTRFRY(X) #X -#define STRFRY(X) dSTRFRY(X) - -int32 TREATY_FUNCTION(FORMAT)(int32 selector, - void *story_file, int32 extent, - void *output, int32 output_extent) -{ - int32 ll, csf; - if ((TREATY_SELECTOR_INPUT & selector) && - (csf=claim_story_file(story_file, extent)) -#include - -static int32 get_story_file_IFID(void *story_file, int32 extent, char *output, int32 output_extent) -{ - int32 i,j; - char ser[7]; - char buffer[32]; - - - if (extent<0x1D) return INVALID_STORY_FILE_RV; - memcpy(ser, (char *) story_file+0x12, 6); - ser[6]=0; - /* Detect vintage story files */ - if (!(ser[0]=='8' || ser[0]=='9' || - (ser[0]=='0' && ser[1]>='0' && ser[1]<='5'))) - { - for(i=0;i 8 - ) return INVALID_STORY_FILE_RV; - for(i=4;i<=14;i+=2) - { - j=read_zint(sf+i); - if (j>extent || j < 0x40) return INVALID_STORY_FILE_RV; - } - - return VALID_STORY_FILE_RV; -} -static int32 get_story_file_extension(void *sf, int32 extent, char *out, int32 output_extent) -{ - int v; - if (!extent) return INVALID_STORY_FILE_RV; - v= ((char *) sf)[0]; - if (v>9) ASSERT_OUTPUT_SIZE(5); - else ASSERT_OUTPUT_SIZE(4); - sprintf(out,".z%d",v); - return 3+(v>9); - -} diff --git a/configure.ac b/configure.ac index 6299c4d..c0f5e90 100644 --- a/configure.ac +++ b/configure.ac @@ -129,8 +129,6 @@ PKG_CHECK_MODULES([PLAYER], [ glib-2.0 >= $GLIB_REQUIRED_VERSION gtk+-3.0 >= $GTK_REQUIRED_VERSION gmodule-2.0 - dnl libgda-4.0 - libsoup-2.4 ]) # Libraries needed to build test programs PKG_CHECK_MODULES([TEST], [ @@ -187,7 +185,6 @@ docs/reference/Makefile docs/reference/version.xml docs/reference/build-selector-table.pl po/Makefile.in -babel/Makefile ]) # Do it diff --git a/tests/Makefile.am b/tests/Makefile.am index 1fed105..6d12176 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -10,7 +10,7 @@ TEST_PLUGIN_LIBTOOL_FLAGS = \ -export-symbols-regex "^glk_main$$" \ -rpath $(abs_builddir) -noinst_PROGRAMS = test-multisession glulxercise plugin-loader test-close babeltest +noinst_PROGRAMS = test-multisession glulxercise plugin-loader test-close test_multisession_SOURCES = test-multisession.c test_multisession_CFLAGS = @TEST_CFLAGS@ $(AM_CFLAGS) @@ -29,10 +29,6 @@ test_close_SOURCES = test-close.c test_close_CFLAGS = @TEST_CFLAGS@ $(AM_CFLAGS) test_close_LDADD = @TEST_LIBS@ $(top_builddir)/libchimara/libchimara.la -babeltest_SOURCES = babeltest.c -babeltest_CFLAGS = @PLAYER_CFLAGS@ $(AM_CFLAGS) -babeltest_LDADD = @PLAYER_LIBS@ $(top_builddir)/babel/libbabel_functions.la $(top_builddir)/babel/libbabel.la $(top_builddir)/babel/libifiction.la - noinst_LTLIBRARIES = first.la model.la gridtest.la splittest.la multiwin.la \ styletest.la soundtest.la test-userstyle.la fileio.la diff --git a/tests/babeltest.c b/tests/babeltest.c deleted file mode 100644 index 2e8827e..0000000 --- a/tests/babeltest.c +++ /dev/null @@ -1,231 +0,0 @@ -#include "babel/babel_handler.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct _metadata { - const gchar *element_name; - gchar *ifid; - gchar *title; - gchar *author; - gchar *firstpublished; - gboolean error; - gchar *error_message; - gchar *error_code; -} metadata; - -void start_element( - GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer data, - GError **error) -{ - metadata *md = (metadata*) data; - md->element_name = element_name; - - if( !strcmp(element_name, "errorCode") ) { - md->error = 1; - md->error_message = ""; - md->error_code = ""; - } - - if( !strcmp(element_name, "ifindex") ) { - md->ifid = ""; - md->title = ""; - md->author = ""; - md->firstpublished = ""; - } -} - -void text( - GMarkupParseContext *context, - const gchar *text, - gsize text_len, - gpointer data, - GError **error) -{ - metadata *md = (metadata*) data; - - if( !strcmp(md->element_name, "errorCode") ) { - md->error_code = g_strndup(text, text_len); - } - else if( !strcmp(md->element_name, "errorMessage") ) { - md->error_message = g_strndup(text, text_len); - } - else if( !strcmp(md->element_name, "ifid") ) { - if( strlen(md->ifid) < text_len ) - md->ifid = g_strndup(text, text_len); - } - else if( !strcmp(md->element_name, "title") ) { - if( strlen(md->title) < text_len ) - md->title = g_strndup(text, text_len); - } - else if( !strcmp(md->element_name, "author") ) { - if( strlen(md->author) < text_len ) - md->author = g_strndup(text, text_len); - } - else if( !strcmp(md->element_name, "firstpublished") ) { - if( strlen(md->firstpublished) < text_len ) - md->firstpublished = g_strndup(text, text_len); - } -} - -void end_element( - GMarkupParseContext *context, - const gchar *element_name, - gpointer data, - GError **error) -{ - if( !strcmp(element_name, "ifindex") ) { - metadata *md = (metadata*) data; - printf("IFID: %s\nTitle: %s\nAuthor: %s\nFirst published: %s\n", md->ifid, md->title, md->author, md->firstpublished); - } -} - -/* - * run a non SELECT command and stops if an error occurs - */ -void -run_sql_non_select(GdaConnection *cnc, const gchar *sql) -{ - GdaStatement *stmt; - GError *error = NULL; - gint nrows; - const gchar *remain; - GdaSqlParser *parser; - - parser = g_object_get_data(G_OBJECT(cnc), "parser"); - stmt = gda_sql_parser_parse_string(parser, sql, &remain, &error); - if(remain) - g_print ("REMAINS: %s\n", remain); - - nrows = gda_connection_statement_execute_non_select(cnc, stmt, NULL, NULL, &error); - if(nrows == -1) - g_error("NON SELECT error: %s\n", error && error->message ? error->message : "no detail"); - g_object_unref(stmt); -} - -int main(int argc, char **argv) { - GError *err = NULL; - metadata data; - data.error = 0; - - if(argc < 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - - g_type_init(); - - babel_init(argv[1]); - int len = babel_treaty(GET_STORY_FILE_METADATA_EXTENT_SEL, NULL, 0); - gchar *ifiction; - if(len) { - printf("Metadata found in file.\n"); - gchar *buffer = malloc(len * sizeof(gchar)); - babel_treaty(GET_STORY_FILE_METADATA_SEL, buffer, len); - ifiction = g_strndup(buffer, len); - g_free(buffer); - } else { - printf("No metadata found in file, performing IFDB lookup.\n"); - gchar *ifid = malloc(TREATY_MINIMUM_EXTENT * sizeof(gchar)); - if( !babel_treaty(GET_STORY_FILE_IFID_SEL, ifid, TREATY_MINIMUM_EXTENT) ) { - fprintf(stderr, "Unable to create an IFID (A serious problem occurred while loading the file).\n"); - babel_release(); - return 1; - } - printf("Looking up IFID: %s.\n", ifid); - babel_release(); - - SoupSession *session = soup_session_async_new(); - char *uri_string = g_strconcat("http://ifdb.tads.org/viewgame?ifiction&ifid=", ifid, NULL); - SoupMessage *message = soup_message_new("GET", uri_string); - g_free(uri_string); - soup_message_headers_append(message->request_headers, "Connection", "close"); - if(soup_session_send_message(session, message) != 200) - g_printerr("ERROR: did not get HTTP status 200\n"); - ifiction = g_strndup(message->response_body->data, message->response_body->length); - g_object_unref(message); - g_object_unref(session); - } - - ifiction = g_strchomp(ifiction); - - GMarkupParser xml_parser = {start_element, end_element, text, NULL, NULL}; - GMarkupParseContext *context = g_markup_parse_context_new(&xml_parser, 0, &data, NULL); - - if( g_markup_parse_context_parse(context, ifiction, strlen(ifiction), &err) == FALSE ) { - fprintf(stderr, "Metadata parse failed: %s\n", err->message); - } - - g_markup_parse_context_free(context); - g_free(ifiction); - - babel_release(); - - // Check for errors - if(data.error) { - fprintf(stderr, "ERROR %s: %s\n", data.error_code, data.error_message); - return 1; - } - - // Open DB connection - GdaConnection *cnc; - GdaSqlParser *sql_parser; - - gda_init(); - cnc = gda_connection_open_from_string("SQLite", "DB_DIR=.;DB_NAME=library", NULL, GDA_CONNECTION_OPTIONS_NONE, &err); - if(!cnc) { - fprintf(stderr, "Could not open connection to SQLite database in library.db file: %s\n", err && err->message ? err->message : "No details"); - return 1; - } - - sql_parser = gda_connection_create_parser(cnc); - if(!sql_parser) // cnc does not provide its own parser, use default one - sql_parser = gda_sql_parser_new(); - - g_object_set_data_full(G_OBJECT(cnc), "parser", sql_parser, g_object_unref); - - // Create stories table - //run_sql_non_select(cnc, "DROP TABLE IF EXISTS stories"); - run_sql_non_select(cnc, "CREATE TABLE IF NOT EXISTS stories (ifid text not null primary key, title text, author text, firstpublished text)"); - - // Populate the table - GValue *v1, *v2, *v3, *v4; - v1 = gda_value_new_from_string(data.ifid, G_TYPE_STRING); - v2 = gda_value_new_from_string(data.title, G_TYPE_STRING); - v3 = gda_value_new_from_string(data.author, G_TYPE_STRING); - v4 = gda_value_new_from_string(data.firstpublished, G_TYPE_STRING); - - if( !gda_insert_row_into_table(cnc, "stories", &err, "ifid", v1, "title", v2, "author", v3, "firstpublished", v4, NULL) ) { - g_warning("Could not INSERT data into the 'stories' table: %s\n", err && err->message ? err->message : "No details"); - } - - gda_value_free(v1); - gda_value_free(v2); - gda_value_free(v3); - gda_value_free(v4); - - // Dump the table contents - GdaDataModel *data_model; - GdaStatement *stmt = gda_sql_parser_parse_string(sql_parser, "SELECT * FROM stories", NULL, NULL); - data_model = gda_connection_statement_execute_select(cnc, stmt, NULL, &err); - if(!data_model) - g_error("Could not get the contents of the 'stories' table: %s\n", err && err->message ? err->message : "No details"); - printf("Dumping library table:\n"); - gda_data_model_dump(data_model, stdout); - - g_object_unref(stmt); - g_object_unref(data_model); - - gda_connection_close(cnc); - return 0; -}