/* name uoapi.c title Unix WP UOAPInterface Sample Program Copyright (C) 1992 WordPerfect Corp., All Rights Reserved ------------------------------------------------------------*/ #include "uoapi.h" #define READ 0 #define WRITE 1 static struct { /* structure to store pipe file descriptors */ int out[2]; int in[2]; } pipes; static char fds[9]; /* temp for converting fds to strings */ char *params[5]; /* parameter data for exec call */ char ppath[] = "wpbin/xwp"; /* path and name of WordPerfect executable */ char thirds[] = "-third"; /* command line parameter to send to WordPerfect */ char tmp1[] = "-L"; char tmp2[] = "Q:NHVEAG"; int cpid; /* pid of WordPerfect process */ /* Utility routine */ /* 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; } /* Utility routine */ /* 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; } /* Utility routine */ /* convert an integer into "cnt" bytes in Intel order */ IVALtoB(ival,b,cnt) unsigned int ival; unsigned char *b; int cnt; { int i; for (i=0;i>= 8; } } /* Utility routine */ /* convert an integer into 4 bytes in Intel order */ void ItoB(ival,b) unsigned int ival; unsigned char *b; { IVALtoB(ival,b,4); } /* Utility routine */ /* convert an integer into 2 bytes in Intel order */ void StoB(ival,b) unsigned int ival; unsigned char *b; { IVALtoB(ival,b,2); } /* Utility routine */ /* convert a byte string to a word string */ int btowstr(char *s, char *b) { int i = 0; while (*s) { b[i++] = *s++; b[i++] = 0; } b[i++] = 0; b[i++] = 0; return i; /* return the length of the word string */ } /* Utility routine */ /* 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 */ } } /* A rudimentary Third Party program to inteface with WP60 UNIX */ main(argc,argv) char *argv[]; { char inbuf[256]; char tmpbuf[256]; char *bufptr; /* variables to save data from the initialization packet */ int in_len; int total_len; int token; int name_len; char name[128]; int product; int major; int minor; char language[3]; int i; /* open pipe to use in writting to WP */ if (pipe(pipes.out) == -1) { exit (1); } /* open pipe to use in reading from WP */ if (pipe(pipes.in) == -1 ) { exit (1); } /* convert pipe fds to strings to pass on command line to WP */ sprintf(fds,"%d",pipes.out[READ]); strcat(fds,","); sprintf(fds+strlen(fds),"%d",pipes.in[WRITE]); /* set up command line parameter list to pass to WP */ params[0] = (char *) ppath; params[1] = (char *) thirds; params[2] = (char *) fds; params[3] = tmp1; params[4] = tmp2; params[5] = 0; /* start WP */ if (cpid = fork()) { if (cpid == -1) { exit (1); } } else { if (execv(ppath,params)) { exit (1); } } /* Read the initiaialization packet from WP */ /* and save the initial data */ bread(pipes.in[READ],inbuf,2); /* read the length of the packet */ total_len = BtoS(inbuf); /* save packet length */ bread(pipes.in[READ],inbuf+2,total_len);/* read remainder of packet */ bufptr = inbuf+2; token = BtoS(bufptr); /* extract the init token */ bufptr += 2; name_len = BtoS(bufptr); /* extract the name lenth */ bufptr += 2; strcpy(name,bufptr); /* extract the logical name */ bufptr += name_len; product = *bufptr++; /* extract the product code */ major = *bufptr++; /* extract the major version # */ minor = *bufptr++; /* extract the minor version # */ language[0] = *bufptr++; /* extract the language string */ language[1] = *bufptr; language[2] = 0; /* return a packet to let WP know we are here */ StoB(4,inbuf); /* length of return packet (4) */ StoB(0,inbuf+2); /* token lower bound */ StoB(0xffff,inbuf+4); /* token upper bound */ write(pipes.out[WRITE],inbuf,6); /* send the packet */ for (;;) { /* handle tokens */ bread(pipes.in[READ],inbuf,2); /* get the packet size */ in_len = BtoS(inbuf); bread(pipes.in[READ],inbuf+2,in_len); /* read the packet */ token = BtoS(inbuf+2); /* get the token value */ if (token == THIRD_EXIT_TOK) { /* Is WP exiting ? */ printf("EXITING\n"); /* yes - so we exit also */ exit(0); } if (token == Type) { /* a regular character ? */ int cnt; /* yes */ token = BtoS(inbuf+9); /* get the character */ if (0 && token >= 'a' && token <= 'z') { /* THIS CODE SETS AND THEN GETS A MERGE VARIABLE */ cnt = 2; StoB(THIRD_SET_MERGE_TOK,tmpbuf+2); cnt += 2; cnt += btowstr("abc",tmpbuf+cnt);/* set the variable "abc" */ cnt += btowstr("xyz",tmpbuf+cnt);/* to have the value "xyz" */ StoB(cnt-2,tmpbuf); write(pipes.out[WRITE],tmpbuf,cnt); /* set merge variable */ bread(pipes.in[READ],tmpbuf,2); /* get result */ total_len = BtoS(tmpbuf); bread(pipes.in[READ],tmpbuf+2,total_len); cnt = 2; StoB(THIRD_GET_MERGE_TOK,tmpbuf+2); cnt += 2; cnt += btowstr("abc",tmpbuf+cnt);/* get the variable "abc" */ StoB(cnt-2,tmpbuf); write(pipes.out[WRITE],tmpbuf,cnt); /* get merge variable */ bread(pipes.in[READ],tmpbuf,2); /* get result */ total_len = BtoS(tmpbuf); bread(pipes.in[READ],tmpbuf+2,total_len); /* THIS CODE GETS A SYSTEM VARIABLE */ StoB(4,tmpbuf); StoB(THIRD_GET_SYSTEM_TOK,tmpbuf+2); StoB(QMarginRight,tmpbuf+4); /* get the right margin value */ write(pipes.out[WRITE],tmpbuf,6); bread(pipes.in[READ],tmpbuf,2); total_len = BtoS(tmpbuf); bread(pipes.in[READ],tmpbuf+2,total_len); } /* This code increment the character that was typed */ /* and sends it back to WP to be handled */ token++; if (token > 'z') { token = 'a'; } StoB(token,inbuf+9); write(pipes.out[WRITE],inbuf,in_len+2); } else { /* send token back unchanged */ write(pipes.out[WRITE],inbuf,in_len+2); } } }