[comp.lang.postscript] eexec?

marmar@mtk.UUCP (Mark Martino) (07/07/90)

If one is not using an Adobe interpreter, eexec is not handled very
gracefully.  Usually the printer just skips the rest of the file and
goes into idle mode and waits for a new file without printing anything.
It often doesn't even seem to know enough to substitute a font and avoid
eexec altogether.

Is there a way to jump over the part of the PostScript file that
involves eexec and the data eexec would use if it were there and
continue on with the rest of the file?

I noticed in the file dumps I've examined that eexec is usually immediately
preceeded by currentfile and followed by what appears to be some font
data which is then followed by a cleartomark.  Is there a way to skip
from the eexec to the cleartomark as though nothing happened and
continue with the file so that everything else prints?

Anyone?...  Anyone?...

woody@chinacat.Unicom.COM (Woody Baker @ Eagle Signal) (07/10/90)

In article <1223@mtk.UUCP>, marmar@mtk.UUCP (Mark Martino) writes:
> If one is not using an Adobe interpreter, eexec is not handled very
> gracefully.  Usually the printer just skips the rest of the file and
> 
> Is there a way to jump over the part of the PostScript file that
> involves eexec and the data eexec would use if it were there and
> continue on with the rest of the file?

eexec is fairly easy to decrypt.  What I would do is to decrypt the eexec
stuff into it's original form, and then download the file.  The Adobe
black book (type 1 font book) documents it.  Don Lancaster published
a routine in the Computer Shopper (written in PostScript) to do that.
There are several 'C' routines floating around that let you do it.
I have one that I use quite a bit.  Unfortunatly, the source is on my
machine at work, so I can't dump it down here, but I will do that
and post it here shortly.  If you decrpt the eexec stuff then it should
go through o.k.  You might have to hexify it first.

I have discovered that Appletalk and the serial port handle things
diffrently when you send stuff like that.  for example, the following
apparently works on  appletalk, but flat fails over the serial port.

currentfile 200 string readstring
22aa1f2f.....(200 bytes worth of hex data)

Under the serial port, if you send a cr/lf in the middle of the hex
string, it will give you an error message.  The only way that I have
found to make it work, is to bracket the hex data with
<.....hex....>   That works.  I have recieved several cexec files that
flat would not work until the <> was wrapped around the hex.  The RED
book specifies that the <> are required, but apparently does not
enforce it over appletalk.


Cheers
Woody

woody@chinacat.Unicom.COM (Woody Baker @ Eagle Signal) (07/10/90)

Here are the encrypt and decrypt routines.  The versions that handle
files, are an adaptation of the other two, as they really did not work
correctly under MS-DOS.  MS-DOS 'C' attempts to be "unix compatable"
and as such, when it sees a 0x0D, it converts it to a linefeed.
This has a way of completely messing up the conversion of a binary
file that happens to have a 0x0d in it.  The file versions avoid
it by using the "b" specifier in the file opening code.  This allows
uncooked binary code.  There is one other non-portablilty.  the declaration
of unsigned short int 0xhhhh; will fail on an 8 bit machine.  Short will
be a byte, and since we are working with 16 bits here.....


#include "stdio.h"


/*
	routine takes an encrypted eexec file and creates a
	decrypted eexec file.  First cut is much simpler than
	the full decryption would be.  Full decryption will handle
	multiple keys, and have the flag to encrypt or decrypt things.
*/

FILE *infile,*outfile;

main(argc,argv)
char *argv[];
int argc;
{
int first =4;
int state=0xD971;
int c;
char decrptd;

	if(argc !=3)
		{
		printf("usage:  decrpt infile outfile\n");
		exit(0);
		};
	infile=fopen(argv[1],"rb");
	outfile=fopen(argv[2],"wb");
	
	while(fscanf(infile,"%2x",&c)>0)
		{
	/*	if(first !=0)	
			{
			first--;
			}
		else
			{ */
			decrptd= c ^ (state >>8);
			if(first !=0)
				{
				first--;
				}
			else
				{	
				fputc(decrptd,outfile);
				}
			state=state + c;
			state=state * 0xCE6D;
			state=state + 0x58BF;
		/*	} */
		}
	fclose(infile);
	fclose(outfile);	
}				
		
	

/* Quickie to convert postscript from stdin to eexec format on stdout */

#include "stdio.h"

static unsigned short buffer = 0xd971;
static unsigned long startup = 0xac7252f3; /* 00000000or whatever you want */

main(argc,argv)
char *argv[];
int argc;
{
  unsigned char input;
  unsigned char output;
  int init = 4;
  int i;
  int result;
  FILE *infile,*outfile;

	if(argc !=4)
		{
		printf("usage: encrypt startkey(long hex) infile outfile\n");
		}
	infile=fopen(argv[2],"r");
	outfile=fopen(argv[3],"wb");
	sscanf(argv[1],"%lx",&startup);
		
  fprintf(outfile,"%08lx",startup);
  for (i=0;i<4;++i)
    {
      input = (startup >> ((3-i)*8));
      buffer = (input + buffer) * 0xce6d + 0x58bf;
    }  

  for(;;)
    {
      for (i=0;i<(32-init);++i)
        {
          input = result = fgetc(infile);
          if ((int)result == EOF)
            break;
          output = (input ^ (buffer>>8));
          buffer = (output + buffer) * 0xce6d + 0x58bf;
          fprintf(outfile,"%02.2x",output);
        }
      init = 0;
      fprintf(outfile,"\n");
      if ((int) result == EOF)
      break;
    }
    fclose(infile);
    fclose(outfile);
}


/* Quickie to convert postscript from stdin to eexec format on stdout */

#include "stdio.h"

static unsigned short buffer = 0xd971;
static unsigned long startup = 0xac7252f3; /* 00000000or whatever you want */

main()
{
  unsigned char input;
  unsigned char output;
  int init = 4;
  int i;
  int result;

  printf("%08lx",startup);
  for (i=0;i<4;++i)
    {
      input = (startup >> ((3-i)*8));
      buffer = (input + buffer) * 0xce6d + 0x58bf;
    }  

  for(;;)
    {
      for (i=0;i<(32-init);++i)
        {
          input = result = getchar();
          if ((int)result == EOF)
            break;
          output = (input ^ (buffer>>8));
          buffer = (output + buffer) * 0xce6d + 0x58bf;
          printf("%02x",output);
        }
      init = 0;
      printf("\n");
      if ((int) result == EOF)
      break;
    }
}

/* Quickie to convert eexec format from stdin to postscript on stdout */

#include <stdio.h>

/* Written by Carsten Wiethoff 1989 */
/* You may do what you want with this code, 
   as long as this notice stays in it */

static unsigned short buffer = 0xd971;

main()
{
  unsigned int input;
  char output;
  int ignore = 4;
  int result;

  do
    {
      result = scanf(" %2x",&input);
      if ( (result == EOF) || (result == 0) )
        break;
      output = input ^ (buffer>>8);
      buffer = (input + buffer) * 0xce6d + 0x58bf;
      if ( ignore > 0 ) 
        {
          ignore--;
        }
      else
        {
          printf("%c",output);
        }
    } while (1);
}


Cheers
Woody

kevina@apple.com (This space for rent) (07/12/90)

In article <1388@chinacat.Unicom.COM> woody@chinacat.Unicom.COM (Woody 
Baker @ Eagle Signal) writes:
> I have discovered that Appletalk and the serial port handle things
> diffrently when you send stuff like that.  for example, the following
> apparently works on  appletalk, but flat fails over the serial port.
> 
> currentfile 200 string readstring
> 22aa1f2f.....(200 bytes worth of hex data)
> 
> Under the serial port, if you send a cr/lf in the middle of the hex
> string, it will give you an error message.  The only way that I have
> found to make it work, is to bracket the hex data with
> <.....hex....>   That works.  I have recieved several cexec files that
> flat would not work until the <> was wrapped around the hex.  The RED
> book specifies that the <> are required, but apparently does not
> enforce it over appletalk.
> 
Notice that you used "readstring" in the above example instead of 
"readhexstring".  Readstring only reads until the first newline, while readhexstring will ignore non-hexadecimal characters (like cr/lf).  The reason that your example works on AppleTalk but not on serial probably has to do with the different handling of newlines. 

It is a fluke of eexec that the same data produces the same results whether bracketed by <> or not (see section 7.2 of the Black Book for an explanation of why) -- in all other situations the angle brackets are required to specify hex data.

--Kevin Andresen [kevina@apple.com]
"Orange whip?  Orange whip?  Three orange whips."

kevina@apple.com (This space for rent) (07/12/90)

Ack!  Too quick on the send button (and too slow on the Red Book...)

In article <9101@goofy.Apple.COM> I write:
> Notice that you used "readstring" in the above example instead of 
> "readhexstring".  Readstring only reads until the first newline, while 
readhexstring will ignore non-hexadecimal characters (like cr/lf).  The 
reason that your example works on AppleTalk but not on serial probably has 
to do with the different handling of newlines. 

What I really meant to say was readstring treats the newline character(s) 
as data.  Readline is the operator that reads until an end-of-line 
indication.  Readhexstring is still the operator of choice.  Now I'm 
confused, though, as to why it would work under AppleTalk and not serial.  
How do you send over AppleTalk?  How about an example?

--Kevin Andresen [kevina@apple.com]
"Orange whip?  Orange whip?  Three orange whips."

glenn@heaven.woodside.ca.us (Glenn Reid) (07/12/90)

In article <9102@goofy.Apple.COM> kevina@apple.com (This space for rent) writes:
|In article <9101@goofy.Apple.COM> I write:
|> Notice that you used "readstring" in the above example instead of 
|> "readhexstring".  Readstring only reads until the first newline, while 
|readhexstring will ignore non-hexadecimal characters (like cr/lf).  The 
|reason that your example works on AppleTalk but not on serial probably has 
|to do with the different handling of newlines. 

|What I really meant to say was readstring treats the newline character(s) 
|as data.  Readline is the operator that reads until an end-of-line 
|indication.  Readhexstring is still the operator of choice.  Now I'm 
|confused, though, as to why it would work under AppleTalk and not serial.  
|How do you send over AppleTalk?  How about an example?

I think you have it right.  As I remember it, the serial driver converts
CR to LF, and it also converts CRLF to LF, which is probably where the
trouble starts.  If you start with two characters and end up with one, you
have a different number of bytes.  Over AppleTalk, CR and LF are just
data as far as the protocol is concerned.

|--Kevin Andresen [kevina@apple.com]
|"Orange whip?  Orange whip?  Three orange whips."

-- 
 Glenn Reid				PostScript/NeXT consultant
 glenn@heaven.woodside.ca.us		Independent Software Developer
 ..{adobe,next}!heaven!glenn		Unparalleled Quality

glenn@heaven.woodside.ca.us (Glenn Reid) (07/12/90)

In article <9102@goofy.Apple.COM> kevina@apple.com (This space for rent) writes:

>--Kevin Andresen [kevina@apple.com]
>"Orange whip?  Orange whip?  Three orange whips."

--Glenn Reid [glenn@heaven.woodside.ca.us]
"We're 120 miles from Chicago; we have a full tank of gas, a half a pack
 of cigarettes, it's dark out, and we're wearing sunglasses.  Let's go."

-- 
 Glenn Reid				PostScript/NeXT consultant
 glenn@heaven.woodside.ca.us		Independent Software Developer
 ..{adobe,next}!heaven!glenn		Unparalleled Quality