/** Same as UNIXTPI.C except its run from the commandd line **/ #include #include #include #include #define READ 0 #define WRITE 1 static int gui; static struct { /* structure to store pipe file descriptors */ int out[2]; int in[2]; } thirdpipes; static char fds[9]; /* temp for converting fds to strings */ char *params[10]; char ppath[] = "/wp51/master51/wpbin/xwp"; char thirds[] = "-third"; char inname[] = "temp.dat"; char outname[] = "temp.txt"; int cpid; char message[] = "You pressed the B Key!"; /* convert 4 bytes in Intel order into an unsigned int (32 bits) */ static unsigned long BtoI(b) unsigned char *b; { unsigned long val; val = *b++; val += (unsigned int)*b++ << 8; val += (unsigned int)*b++ << 16; val += (unsigned int)*b << 24; return val; } /* convert 2 bytes in Intel order into an unsigned int (32 bits) */ static unsigned long BtoS(b) unsigned char *b; { unsigned long val; val = *b++; val += (unsigned int)*b++ << 8; return val; } /******************************************************************** * Function: bread * * * * WordPerfect 5.1 doesn't put information in the pipe all at once. * * It will get some information, put it in the pipe, get the next * * piece of information, put it in the pipe, and so on. * * * * WP 5.1 may do several "gets" to produce one buffer. Because of * * this, your TPI program should NEVER read the pipe directly. If * * it does, you will never have a complete buffer to read from and * * you will not know which part of the current buffer you are * * getting the information for. * * * * The function "bread" has been provided for this purpose. This * * function will gather the size of the current buffer and will * * return the information for a buffer only when the buffer is * * complete. Your program should always use this function. * ********************************************************************/ /* read cnt bytes from file decriptor fd */ static bread(fd,buf,cnt) int fd,cnt; char *buf; { int br = 0; for (;;) { br += read(fd,buf+br,cnt-br); /* read bytes */ if (br == cnt) { /* did we get them all ? */ break; /* yes - return */ } /* no - loop for another read */ } } main(argc,argv) char *argv[]; { unsigned char buf[256]; int cnt,i; int in,out; int len; char *tptr; unsigned long fsize, macoff, state; /* pipe to write to WP */ if (pipe(thirdpipes.out) == -1) { exit (1); } /* pipe to read from WP */ if (pipe(thirdpipes.in) == -1 ) { exit (1); } /* convert pipe fds to strings */ sprintf(fds,"%d",thirdpipes.out[READ]); strcat(fds,","); sprintf(fds+strlen(fds),"%d",thirdpipes.in[WRITE]); /* set up parameter list for third party process */ params[0] = (char *) ppath; params[1] = "-M"; /* Switch meaningless in shipping WP */ params[2] = (char *) thirds; params[3] = (char *) fds; params[4] = (char *) inname; params[5] = 0; /* exec WP */ if (cpid = fork()) { if (cpid == -1) { exit (1); } } else { if (execv(ppath,params)) { exit (1); } } bread(thirdpipes.in[READ],buf,2);/* read the length from the first packet */ cnt = buf[0] + ((int)buf[1] << 8); /* read the intialization packet */ bread(thirdpipes.in[READ],buf+2,cnt); /* it is cnt bytes long */ len = BtoS(buf+8); gui = buf[10+len] == 1; /* return a packet to let the WPApp know we are here */ buf[0] = 4; /* length of return packet (lo byte) */ buf[1] = 0; /* length of return packet (hi byte) */ buf[2] = 'B'; /* token lower bound (lo byte) */ buf[3] = 0; /* token lower bound (hi byte) */ buf[4] = 0x26; /* token upper bound (lo byte) */ buf[5] = 0x40; /* token upper bound (hi byte) */ write(thirdpipes.out[WRITE],buf,6); /* send the packet */ for (;;) { /* handle tokens */ bread(thirdpipes.in[READ],buf,2); /* read the count bytes */ cnt = buf[0] + ((int)(buf[1]) << 8); bread(thirdpipes.in[READ],buf+2,cnt); /* read the rest of the packet */ state = BtoI(buf+2); if (state == 0xffffffff) { /* exit token */ exit(0); /* yes - exit now */ } if (state & 0x100000) { /* check for bit 20 */ buf[0] = 0; buf[1] = 0; write(thirdpipes.out[WRITE],buf,2); continue; } if (cnt == 6) { /* regular characters */ if (gui && buf[7] == 0x40 && buf[6] == 0x26) { /* replace the Close token with a Save token and an Exit */ /* have the Save do an ascii conversion */ buf[6] = 0x29; buf[7] = 0x20; strcpy(buf+10,outname); /* file name for "Save" */ len = strlen(outname) + 1; buf[10+len] = 3; /* save as ascii */ buf[11+len] = 0; /* don't condense */ len += 2; buf[8] = len & 0xff; buf[9] = (len >> 8) & 0xff; len += 4; if (len % 2) { /* each token must start on an even boundary */ len++; } buf[len+6] = 0x26; buf[len+7] = 0x20; len += 6; buf[0] = len & 0xff; buf[1] = (len >> 8) & 0xff; write(thirdpipes.out[WRITE],buf,len+2); } else if (buf[7] == 0 && buf[6] == 'B') { /* Replace the B key with a message */ for (i=0;i> 8) & 0xff; write(thirdpipes.out[WRITE],buf,2*strlen(message)+6); } else { buf[0] = 2; buf[1] = 0; buf[2] = buf[6]; /* send it back */ buf[3] = buf[7]; write(thirdpipes.out[WRITE],buf,4); } } else { /* send buffer back unchanged */ cnt -= 4; for (i=0;i> 8) & 0xff; write(thirdpipes.out[WRITE],buf+4,cnt+2); } } }