home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume19
/
untype1
/
part01
/
chars.c
next >
Wrap
C/C++ Source or Header
|
1991-05-19
|
6KB
|
239 lines
/*
* chars.c -- decrypt an Adobe font file of encrypted CharStrings
*
* Chris B. Sears
*/
#include <stdio.h>
#include <strings.h>
#define TRUE 1
#define FALSE 0
#ifndef SEEK_SET
#define SEEK_SET 0 /* Some <stdio.h> files don't have this */
#endif
int lenIV = 4; /* the default CharString salt length is 4 */
typedef struct {
char *command;
int value;
} Command;
Command commands[] = {
{ "notdefined_c0", 0 }, { "hstem", 1 },
{ "notdefined_c2", 2 }, { "vstem", 3 },
{ "vmoveto", 4 }, { "chars_rlineto", 5 },
{ "hlineto", 6 }, { "vlineto", 7 },
{ "rrcurveto", 8 }, { "chars_closepath", 9 },
{ "callsubr", 10 }, { "return", 11 },
{ "escape", 12 }, { "hsbw", 13 },
{ "endchar", 14 }, { "notdefined_c16", 15 },
{ "notdefined_c16", 16 }, { "notdefined_c17", 17 },
{ "notdefined_c18", 18 }, { "notdefined_c19", 19 },
{ "notdefined_c20", 20 }, { "chars_rmoveto", 21 },
{ "hmoveto", 22 }, { "notdefined_c23", 23 },
{ "notdefined_c24", 24 }, { "notdefined_c25", 25 },
{ "notdefined_c26", 26 }, { "notdefined_c27", 27 },
{ "notdefined_c28", 28 }, { "notdefined_c29", 29 },
{ "vhcurveto", 30 }, { "hvcurveto", 31 }
};
Command escapes[] = {
{ "dotsection", 0 }, { "vstem3", 1 },
{ "hstem3", 2 }, { "notdefined_e3", 3 },
{ "notdefined_e4", 4 }, { "notdefined_e5", 5 },
{ "seac", 6 }, { "sbw", 7 },
{ "notdefined_e8", 8 }, { "notdefined_e9", 9 },
{ "notdefined_e10", 10 }, { "notdefined_e11", 11 },
{ "chars_div", 12 }, { "notdefined_e13", 13 },
{ "notdefined_e14", 14 }, { "testadd", 15 },
{ "callothersubr", 16 }, { "chars_pop", 17 },
{ "notdefined_e18", 18 }, { "notdefined_e19", 19 },
{ "notdefined_e20", 20 }, { "notdefined_e21", 21 },
{ "notdefined_e22", 22 }, { "notdefined_e23", 23 },
{ "notdefined_e24", 24 }, { "notdefined_e25", 25 },
{ "notdefined_e26", 26 }, { "notdefined_e27", 27 },
{ "notdefined_e28", 28 }, { "notdefined_e29", 29 },
{ "notdefined_e30", 30 }, { "notdefined_e31", 31 },
{ "notdefined_e32", 32 }, { "setcurrentpoint", 33 }
};
#define MAX_ESCAPE 33
#define CR 4330
#define CC1 52845
#define CC2 22719
unsigned short int cr, cc1, cc2;
unsigned char
DeCrypt(cipher)
unsigned char cipher;
{
unsigned char plain;
plain = (cipher ^ (cr >> 8));
cr = (cipher + cr) * cc1 + cc2;
return plain;
}
/*
* This is necessary because some C libraries aren't ANSI C compliant yet.
*/
char *
StrStr(string, match)
char *string, *match;
{
int i, length;
length = strlen(match);
for (i = strlen(string) - length; i >= 0; i--, string++)
if (!strncmp(match, string, length))
return string;
return NULL;
}
void
main(argc, argv)
int argc;
char **argv;
{
FILE *in, *out;
unsigned char in_buff[BUFSIZ], byte, *rd_pos, *count_pos;
int line_pos, i, count;
long value;
if (argc != 3) {
fprintf(stderr, "Usage: %s input output\n", argv[0]);
exit(0);
}
if ((in = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "%s: can't open %s\n", argv[0], argv[1]);
exit(0);
}
if ((out = fopen(argv[2], "w")) == NULL) {
fprintf(stderr, "%s: can't open %s\n", argv[0], argv[2]);
exit(0);
}
setbuf(out, NULL);
/*
* TODO: rewrite this so as not to use a seek and to use stdin.
*/
for (;;) {
line_pos = ftell(in);
if (fgets((char *) in_buff, BUFSIZ, in) == NULL)
break;
if (strncmp("/lenIV", (char *) in_buff, 6) == 0)
lenIV = atoi(in_buff + 7);
if ((rd_pos = (unsigned char *) StrStr(in_buff, " RD ")) == NULL) {
if ((rd_pos = (unsigned char *) StrStr(in_buff, " -| ")) == NULL) {
fputs((char *) in_buff, out);
continue;
}
}
/*
* We found an encrypted CharString.
* Back up and determine the number of encrypted characters.
* These have the form: dup 105 9 RD 9bytesofdata noaccess put
*/
for (count_pos = rd_pos - 1;
(count_pos >= in_buff) && (*count_pos != ' ');
count_pos--)
;
if (*count_pos == ' ') /* This can be at the beginning of a line */
count_pos++;
/*
* Write out the beginning of the string without the RD stuff.
*/
fwrite(in_buff, count_pos - in_buff, 1, out);
fprintf(out, "{");
count = atoi(count_pos);
/*
* Seek to and read the binary data.
*/
fseek(in, line_pos + (rd_pos - in_buff) + 4, SEEK_SET);
fread(in_buff, BUFSIZ, 1, in);
/*
* We must restart the decryption machinery for each CharString.
*/
cr = CR;
cc1 = CC1;
cc2 = CC2;
/*
* Skip over the salt.
*/
for (i = 0; i < lenIV; i++)
byte = DeCrypt(in_buff[i]);
/*
* Translate the buffer.
*/
for (; i < count;) {
byte = DeCrypt(in_buff[i++]);
if (byte == 11) { /* return */
fprintf(out, " %s", commands[byte].command);
break;
} else if (byte == 12) { /* escape */
byte = DeCrypt(in_buff[i++]);
if (byte > MAX_ESCAPE)
fprintf(out, " not_defined_e%d", byte);
else
fprintf(out, " %s", escapes[byte].command);
continue;
} else if (byte < 32)
fprintf(out, " %s", commands[byte].command);
if (byte >= 32) {
if (byte <= 246)
fprintf(out, " %d", byte - 139);
else if ((byte >= 247) && (byte <= 250))
fprintf(out, " %d",
(byte - 247) * 256 + DeCrypt(in_buff[i++]) + 108);
else if ((byte >= 251) && (byte <= 254))
fprintf(out, " %d",
-(byte - 251) * 256 - DeCrypt(in_buff[i++]) - 108);
else if (byte == 255) {
value = DeCrypt(in_buff[i++]);
value <<= 8;
value += DeCrypt(in_buff[i++]);
value <<= 8;
value += DeCrypt(in_buff[i++]);
value <<= 8;
value += DeCrypt(in_buff[i++]);
fprintf(out, " %d", value);
}
}
}
fprintf(out, " }");
/*
* Seek just past the CharString bytes and continue.
*/
fseek(in, line_pos + (rd_pos - in_buff) + 4 + i, SEEK_SET);
}
fclose(in);
fclose(out);
exit(0);
}