/* binpatch.c Simple non-interactive binary patch utility * DWF 7/19/94 First version and hopefully the last. Just say NO to * creeping features! * * Usage: binpatch infile outfile < patch * * This program is written so that it should work under Messy-DOS, i.e., * it uses temporary files instead of reading the entire binary into memory. * I have successfully compiled it with an old version of Turbo C, but I had * to add an #ifdef to the includes. * * Here is an example patch file. Comments, with # in the first column, * are ignored; the other lines alternate between search-string and * replace-string in hexadecimal. * * # Patches for shareware doom.exe 1.5 beta posted to alt.games.doom by * # ep104@cus.cam.ac.uk (Elias 'CaveMan' Papavassilopoulos) * # * # Fix crash & burn on idkfa + shotgun * B9 09 00 00 00 C7 40 B0 02 00 00 00 * B9 08 00 00 00 C7 40 B0 02 00 00 00 * # * # Enable cheat codes in Nightmare mode * 0F 85 29 03 00 00 83 3D 70 82 02 00 04 * 0F 85 29 03 00 00 83 3D 70 82 02 00 45 */ #include #include #ifndef __TURBOC__ #include #endif /* Names for temporary files */ #define temp1 "temp1" #define temp2 "temp2" /* Maximum length of text lines on input */ /*#define maxlen 80*/ #define maxlen 256 void usage () { puts ("Usage: binpatch infile outfile < patch"); exit (0); } void bail () { unlink (temp1); unlink (temp2); exit (-1); } void dont_clobber (char *fname) { FILE *inf; if ((inf = fopen (fname, "r"))) { printf ("Will not overwrite existing file %s -- rename or delete it\n", fname); exit (-1); } } int get_line (unsigned char line[maxlen], int *len) { char txtlin[maxlen]; int t, tt; *len = 0; do t = (int) fgets (txtlin, maxlen, stdin); while ((txtlin[0] == '#') && t); if (!t) return 0; if (strlen (txtlin) >= maxlen-1) { printf ("Line in patch file >= %d characters: too long\n", maxlen-1); bail (); } t = 0; while (sscanf (txtlin+t, "%x", &tt) == 1) { line[(*len)++] = (unsigned char)tt; while (isalnum (txtlin[t])) t++; while (isspace (txtlin[t])) t++; } return *len; } void search_and_destroy (FILE *inf, FILE *otf, unsigned char srch[maxlen], int srchlen, unsigned char repl[maxlen], int *matches) { int matchnum=0, fchar, t; while ((fchar = fgetc (inf)) != EOF) { if (fchar == (int)srch[matchnum]) { matchnum++; if (matchnum == srchlen) { for (t=0;t