home *** CD-ROM | disk | FTP | other *** search
- /** 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);
- }
- }
- }
-
-