home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
WordPerfect for Linux Bible
/
WP4LinuxBible.iso
/
sdk
/
wpc
/
code
/
unixtpi2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-06-25
|
6KB
|
220 lines
/** Same as UNIXTPI.C except its run from the commandd line **/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#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<strlen(message);i++) {
buf[2*i+6] = message[i];
buf[2*i+7] = 0;
}
buf[0] = (2 * strlen(message) + 4) & 0xff;
buf[1] = ((2 * strlen(message) + 4) >> 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<cnt;i++) {
buf[6+cnt+i] = buf[6+i];
}
cnt += 2;
buf[4] = cnt & 0xff;
buf[5] = (cnt >> 8) & 0xff;
write(thirdpipes.out[WRITE],buf+4,cnt+2);
}
}
}