home *** CD-ROM | disk | FTP | other *** search
/ WordPerfect for Linux Bible / WP4LinuxBible.iso / sdk / wpc / code / unixtpi2.c < prev    next >
C/C++ Source or Header  |  1999-06-25  |  6KB  |  220 lines

  1. /** Same as UNIXTPI.C except its run from the commandd line **/
  2.  
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7.  
  8. #define READ  0
  9. #define WRITE 1
  10.  
  11. static int gui;
  12.  
  13. static struct {         /* structure to store pipe file descriptors */
  14.     int out[2];
  15.     int in[2];
  16. } thirdpipes;
  17.  
  18. static char fds[9];    /* temp for converting fds to strings */
  19. char *params[10];
  20. char ppath[] = "/wp51/master51/wpbin/xwp";
  21. char thirds[] = "-third";
  22. char inname[] = "temp.dat";
  23. char outname[] = "temp.txt";
  24. int cpid;
  25.  
  26. char message[] = "You pressed the B Key!";
  27.  
  28. /* convert 4 bytes in Intel order into an unsigned int (32 bits) */
  29. static unsigned long BtoI(b)
  30. unsigned char *b;
  31. {
  32.     unsigned long val;
  33.  
  34.     val = *b++;
  35.     val += (unsigned int)*b++ << 8;
  36.     val += (unsigned int)*b++ << 16;
  37.     val += (unsigned int)*b << 24;
  38.     return val;
  39. }
  40.  
  41. /* convert 2 bytes in Intel order into an unsigned int (32 bits) */
  42. static unsigned long BtoS(b)
  43. unsigned char *b;
  44. {
  45.     unsigned long val;
  46.  
  47.     val = *b++;
  48.     val += (unsigned int)*b++ << 8;
  49.     return val;
  50. }
  51.  
  52. /********************************************************************
  53.  * Function: bread                                                  *
  54.  *                                                                  *
  55.  * WordPerfect 5.1 doesn't put information in the pipe all at once. *
  56.  * It will get some information, put it in the pipe, get the next   *
  57.  * piece of information, put it in the pipe, and so on.             *
  58.  *                                                                  *
  59.  * WP 5.1 may do several "gets" to produce one buffer.  Because of  *
  60.  * this, your TPI program should NEVER read the pipe directly.  If  *
  61.  * it does, you will never have a complete buffer to read from and  *
  62.  * you will not know which part of the current buffer you are       *
  63.  * getting the information for.                                     *
  64.  *                                                                  *
  65.  * The function "bread" has been provided for this purpose.  This   *
  66.  * function will gather the size of the current buffer and will     *
  67.  * return the information for a buffer only when the buffer is      *
  68.  * complete.  Your program should always use this function.         *
  69.  ********************************************************************/
  70. /* read cnt bytes from file decriptor fd */
  71. static bread(fd,buf,cnt)
  72. int fd,cnt;
  73. char *buf;
  74. {
  75.     int br = 0;
  76.  
  77.     for (;;) {
  78.         br += read(fd,buf+br,cnt-br);    /* read bytes */
  79.         if (br == cnt) {                /* did we get them all ? */
  80.             break;                        /* yes - return */
  81.         }                                /* no - loop for another read */
  82.     }
  83. }
  84.  
  85. main(argc,argv)
  86. char *argv[];
  87. {
  88.     unsigned char buf[256];
  89.     int cnt,i;
  90.     int in,out;
  91.     int len;
  92.     char *tptr;
  93.     unsigned long fsize, macoff, state;
  94.  
  95.     /* pipe to write to WP */
  96.     if (pipe(thirdpipes.out) == -1) {
  97.         exit (1);
  98.     }
  99.  
  100.     /* pipe to read from WP */
  101.     if (pipe(thirdpipes.in) == -1 ) {
  102.         exit (1);
  103.     }
  104.  
  105.     /* convert pipe fds to strings */
  106.     sprintf(fds,"%d",thirdpipes.out[READ]);
  107.     strcat(fds,",");
  108.     sprintf(fds+strlen(fds),"%d",thirdpipes.in[WRITE]);
  109.  
  110.     /* set up parameter list for third party process */
  111.     params[0] = (char *) ppath;
  112.     params[1] = "-M";    /* Switch meaningless in shipping WP */
  113.     params[2] = (char *) thirds;
  114.     params[3] = (char *) fds;
  115.     params[4] = (char *) inname;
  116.     params[5] = 0;
  117.  
  118.     /* exec WP */
  119.     if (cpid = fork()) {
  120.         if (cpid == -1) {
  121.             exit (1);
  122.         }
  123.     }
  124.     else {
  125.         if (execv(ppath,params)) {
  126.             exit (1);
  127.         }
  128.     }
  129.  
  130.     bread(thirdpipes.in[READ],buf,2);/* read the length from the first packet */
  131.  
  132.     cnt = buf[0] + ((int)buf[1] << 8);    /* read the intialization packet */
  133.     bread(thirdpipes.in[READ],buf+2,cnt);        /* it is cnt bytes long */
  134.  
  135.     len = BtoS(buf+8);
  136.     gui = buf[10+len] == 1;
  137.  
  138.     /* return a packet to let the WPApp know we are here */
  139.     buf[0] = 4;                /* length of return packet (lo byte) */
  140.     buf[1] = 0;             /* length of return packet (hi byte) */
  141.     buf[2] = 'B';            /* token lower bound (lo byte) */
  142.     buf[3] = 0;          /* token lower bound (hi byte) */
  143.     buf[4] = 0x26;            /* token upper bound (lo byte) */
  144.     buf[5] = 0x40;             /* token upper bound (hi byte) */
  145.     write(thirdpipes.out[WRITE],buf,6);        /* send the packet */
  146.  
  147.     for (;;) {        /* handle tokens */
  148.         bread(thirdpipes.in[READ],buf,2);        /* read the count bytes */
  149.         cnt = buf[0] + ((int)(buf[1]) << 8);
  150.         bread(thirdpipes.in[READ],buf+2,cnt);    /* read the rest of the packet */
  151.  
  152.         state = BtoI(buf+2);
  153.         if (state == 0xffffffff) {            /* exit token */
  154.             exit(0);                        /* yes - exit now */
  155.         }
  156.         if (state & 0x100000) {        /* check for bit 20 */
  157.             buf[0] = 0;
  158.             buf[1] = 0;
  159.             write(thirdpipes.out[WRITE],buf,2);
  160.             continue;
  161.         }
  162.  
  163.         if (cnt == 6) {        /* regular characters */
  164.             if (gui && buf[7] == 0x40 && buf[6] == 0x26) {
  165.                 /* replace the Close token with a Save token and an Exit */
  166.                 /* have the Save do an ascii conversion */
  167.                 buf[6] = 0x29;
  168.                 buf[7] = 0x20;
  169.                 strcpy(buf+10,outname);    /* file name for "Save" */
  170.                 len = strlen(outname) + 1;
  171.                 buf[10+len] = 3;            /* save as ascii */
  172.                 buf[11+len] = 0;            /* don't condense */
  173.                 len += 2;
  174.                 buf[8] = len & 0xff;
  175.                 buf[9] = (len >> 8) & 0xff;
  176.                 len += 4;
  177.                 if (len % 2) {  /* each token must start on an even boundary */
  178.                     len++;
  179.                 }
  180.                 buf[len+6] = 0x26;
  181.                 buf[len+7] = 0x20;
  182.                 len += 6;
  183.                 buf[0] = len & 0xff;
  184.                 buf[1] = (len >> 8) & 0xff;
  185.  
  186.                 write(thirdpipes.out[WRITE],buf,len+2);
  187.             }
  188.             else if (buf[7] == 0 && buf[6] == 'B') {
  189.                 /* Replace the B key with a message */
  190.                 for (i=0;i<strlen(message);i++) {
  191.                     buf[2*i+6] = message[i];
  192.                     buf[2*i+7] = 0;
  193.                 }
  194.                 buf[0] = (2 * strlen(message) + 4) & 0xff;
  195.                 buf[1] = ((2 * strlen(message) + 4) >> 8) & 0xff;
  196.                 write(thirdpipes.out[WRITE],buf,2*strlen(message)+6);
  197.             }
  198.             else {
  199.                 buf[0] = 2;
  200.                 buf[1] = 0;
  201.                 buf[2] = buf[6];    /* send it back */
  202.                 buf[3] = buf[7];
  203.                 write(thirdpipes.out[WRITE],buf,4);
  204.             }
  205.         }
  206.         else {
  207.             /* send buffer back unchanged */
  208.             cnt -= 4;
  209.             for (i=0;i<cnt;i++) {
  210.                 buf[6+cnt+i] = buf[6+i];
  211.             }
  212.             cnt += 2;
  213.             buf[4] = cnt & 0xff;
  214.             buf[5] = (cnt >> 8) & 0xff;
  215.             write(thirdpipes.out[WRITE],buf+4,cnt+2);
  216.         }
  217.     }
  218. }
  219.  
  220.