[BACK]Return to oxmisc.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / kan96xx / plugin

Annotation of OpenXM/src/kan96xx/plugin/oxmisc.c, Revision 1.29

1.29    ! takayama    1: /*  $OpenXM: OpenXM/src/kan96xx/plugin/oxmisc.c,v 1.28 2015/09/27 08:12:42 takayama Exp $ */
1.1       maekawa     2: #include <stdio.h>
1.25      ohara       3: #include <string.h>
1.1       maekawa     4: #include <sys/types.h>
                      5: #include <sys/stat.h>
                      6: #include <sys/socket.h>
                      7: #include <sys/time.h>
                      8: #include <netinet/in.h>
                      9: #include <netdb.h>
                     10: #include <fcntl.h>
                     11: #include <stdlib.h>
                     12: #include <unistd.h>
                     13: #include <signal.h>
                     14: #include <setjmp.h>
1.19      takayama   15: #include <errno.h>
1.5       takayama   16: #define SET_MYERROROUT { if (MyErrorOut == NULL) MyErrorOut=stdout; }
                     17: /* It is also defined in oxmisc2.c */
                     18: FILE *MyErrorOut = NULL;
1.1       maekawa    19:
                     20: /* Include files to understand object */
                     21: #include "../Kan/datatype.h"
                     22: #include "../Kan/stackm.h"
                     23: #include "../Kan/extern.h"
                     24:
                     25: #include "ox_kan.h"
                     26:
1.28      takayama   27:
1.1       maekawa    28: #define READBUFSIZE 5000
                     29:
1.8       takayama   30: int OxVersion = 200012030;
1.1       maekawa    31: int UseOXPacketSerial = 1;
                     32: int SerialOX = 1;
                     33: extern int Quiet;
                     34:
                     35: static char *OxPortFileName = ".ox.dummy";
                     36:
                     37:
                     38: int readOneByte(int fd)   /* blocking */
                     39: {
                     40:   static char data[1];
                     41:   int size;
                     42:   int ans;
                     43:   int watch = 1;
                     44:
1.5       takayama   45:   SET_MYERROROUT;
1.1       maekawa    46:   if (fd < 0) {
                     47:     fprintf(MyErrorOut,"readOneByte fd < 0 ??? .\n");
                     48:     return(-1);
                     49:   }
                     50:
                     51:   if (oxSocketSelect0(fd,-1)) { /* block */
                     52:     size = read(fd,data,1);
                     53:     if (size == 0) {
1.7       takayama   54:       fprintf(MyErrorOut,"oxSocketSelect0() returns 1, but there is no data. Your peer may be killed.\n");
1.1       maekawa    55:       return(-1);
                     56:     }
                     57:     return(data[0]);
                     58:   }else{
                     59:     fprintf(MyErrorOut,"readOneByte: select error in block mode. Retrying.\n");
                     60:     return(-1);
                     61:   }
                     62: }
                     63:
                     64: int readOneByte_org(int fd)   /* blocking */
                     65: {
                     66:   static char data[READBUFSIZE];
                     67:   static int thisFd = -1;
                     68:   static int from = 0;
                     69:   static int to = 0;
                     70:   int size;
                     71:   int ans;
                     72:   int watch = 1;
                     73:
1.5       takayama   74:   SET_MYERROROUT;
1.1       maekawa    75:   if ((thisFd == -1) && (fd >= 0)) {thisFd = fd;}
                     76:   if (fd < 0) {
                     77:     fprintf(MyErrorOut,"readOneByte fd < 0 ??? .\n");
                     78:     return(-1);
                     79:   }
                     80:
                     81:   if (fd != thisFd) {
                     82:     fprintf(MyErrorOut,"readOneByte can be used only for one fd.\n");
                     83:     fflush(NULL);
                     84:     return(-1);
                     85:   }
                     86:   if (to > from) {
                     87:     ans = data[from];
                     88:     from++;
                     89:     if (watch) {
                     90:       printf("%2x ",ans);
                     91:       fflush(stdout);
                     92:     }
                     93:     return(ans);
                     94:   }
                     95:
                     96:   while (1) {
                     97:     if (oxSocketSelect0(fd,-1)) { /* block */
                     98:       size = read(fd,data,READBUFSIZE-1);
                     99:       if (size == 0) {
1.9       takayama  100:         fprintf(MyErrorOut,"oxSocketSelect0() returns 1, but there is no data. Your peer may be killed.\n");
                    101:         return(-1);
1.1       maekawa   102:       }
                    103:       from = 0;
                    104:       to = size;
                    105:       return(readOneByte(fd));
                    106:     }else{
                    107:       fprintf(MyErrorOut,"readOneByte: select error in block mode. Retrying.\n");  }
                    108:   }
                    109: }
                    110:
                    111: int oxfdGetInt32(int fd)
                    112: {
                    113:   char d[4];
                    114:   int i;
                    115:   for (i=0; i<4; i++) {
                    116:     d[i] = readOneByte(fd);
                    117:   }
                    118:   return(ntohl(* ( (int *)d)));
                    119: }
                    120:
                    121: int oxGetInt32(ox_stream ostream)
                    122: {
                    123:   char d[4];
                    124:   int i;
                    125:   for (i=0; i<4; i++) {
                    126:     d[i] = fp2fgetc(ostream);
                    127:   }
                    128:   return(ntohl(* ( (int *)d)));
                    129: }
                    130: int oxGetCMOInt32(ox_stream ostream)
                    131: {
                    132:   int id;
1.5       takayama  133:   SET_MYERROROUT;
1.1       maekawa   134:   id = oxGetInt32(ostream);
                    135:   if (id != CMO_INT32) {
                    136:     fprintf(MyErrorOut,"It is not CMO_INT32.\n");
                    137:     return(0);
                    138:   }
                    139:   return(oxGetInt32(ostream));
                    140: }
                    141: char *oxGetCMOString(ox_stream ostream) {
                    142:   int id;
                    143:   int size;
                    144:   char *r;
                    145:   int i;
1.5       takayama  146:   SET_MYERROROUT;
1.1       maekawa   147:   id = oxGetInt32(ostream);
                    148:   if (id != CMO_STRING) {
                    149:     fprintf(MyErrorOut,"It is not CMO_STRING.\n");
                    150:     return(NULL);
                    151:   }
                    152:   size = oxGetInt32(ostream);
                    153:   if (size <0) {
                    154:     return(NULL);
                    155:   }else{
                    156:     r = (char *)mymalloc(size+1);
                    157:     for (i=0; i<size; i++) {
                    158:       r[i] = fp2fgetc(ostream);
                    159:     }
                    160:     r[size] = '\0';
                    161:     return(r);
                    162:   }
                    163: }
                    164:
                    165: void oxfdSendSyncBall(int fd)
                    166: {
                    167:   oxfdSendOXheader(fd,OX_SYNC_BALL,SerialOX++);
                    168: }
                    169:
                    170: void oxSendSyncBall(ox_stream os)
                    171: {
                    172:   oxSendOXheader(os,OX_SYNC_BALL,SerialOX++);
                    173: }
                    174:
                    175: int oxWaitSyncBall(ox_stream ostream)
                    176: {
                    177:   int sss;
                    178:   int mtag;
                    179:   while ((mtag = oxGetOXheader(ostream,&sss)) != OX_SYNC_BALL) {
                    180:     fprintf(stderr,"Looking for the next message tag. mtag=%d\n",mtag);
1.9       takayama  181:     /* or stdout */
1.1       maekawa   182:     fflush(NULL);
1.26      takayama  183:        if (mtag == -1) {
1.27      takayama  184:          fprintf(stderr,"Your peer seems to be dead.\n"); return 0;
1.26      takayama  185:        }
1.1       maekawa   186:   }
                    187: }
                    188:
                    189: int oxWaitSyncBall_org(ox_stream ostream)
                    190: {
                    191:   int mtag;
                    192:   char data[4];
                    193:   int c;
1.5       takayama  194:   SET_MYERROROUT;
1.1       maekawa   195:   data[0] = data[1] = data[2] = data[3] = 0xff;
                    196:   while (1) {
                    197:     /* This part should be revised so that this part understands
                    198:        the cmo format.
1.9       takayama  199:     */
1.1       maekawa   200:
                    201:     if ((c = fp2fgetc(ostream)) < 0) {
                    202:       /* never use read directory. readOneByte() is buffers every thing. */
                    203:       fprintf(MyErrorOut,"End of file.\n");
                    204:       return(-1);
                    205:     }
                    206:     data[0] = data[1];
                    207:     data[1] = data[2];
                    208:     data[2] = data[3];
                    209:     data[3] = (char)c;
                    210:     mtag = ntohl(*((int *)(data)));
                    211:     if (mtag == OX_SYNC_BALL) {
                    212:       printf("Found the OX_SYNC_BALL. \n");
                    213:       fflush(NULL);
                    214:       return(mtag);
                    215:     }
                    216:     fprintf(stderr,"Looking for the next message tag.. %2x, mtag=%d\n",c,mtag);
1.9       takayama  217:     /* or stdout */
1.1       maekawa   218:     fflush(NULL);
                    219:   }
                    220: }
                    221:
                    222:
                    223: void oxfdSendCmoNull(int fd)
                    224: {
                    225:   char data[4];
                    226:   *((int *)&data[0]) = htonl(CMO_NULL);
                    227:   write(fd,data,4);
                    228:   fflush((FILE *)NULL);
                    229: }
                    230: void oxSendCmoNull(ox_stream os)
                    231: {
                    232:   char data[4];
                    233:   *((int *)&data[0]) = htonl(CMO_NULL);
                    234:   fp2write(os,data,4);
                    235:   fp2fflush(os);
                    236: }
                    237:
                    238: void oxSendCmoError(ox_stream os)
                    239: {
                    240:   char data[4];
                    241:   *((int *)&data[0]) = htonl(CMO_ERROR);
                    242:   fp2write(os,data,4);
                    243:   fp2fflush(os);
                    244: }
                    245:
                    246: void oxSendCmoError2(ox_stream os,char *s)
                    247: {
                    248:   char data[4];
                    249:   *((int *)&data[0]) = htonl(CMO_ERROR2);
                    250:   fp2write(os,data,4);
                    251:   fp2fflush(os);
                    252:   oxSendCmoString(os,s);
                    253: }
                    254:
                    255: void oxfdSendInt32(int fd,int k)
                    256: {
                    257:   char data[4];
                    258:   *((int *)&data[0]) = htonl(k);
                    259:   write(fd,data,4);
                    260:   fflush((FILE *)NULL);
                    261: }
                    262: void oxSendInt32(ox_stream os,int k)
                    263: {
                    264:   char data[4];
                    265:   *((int *)&data[0]) = htonl(k);
                    266:   fp2write(os,data,4);
                    267:   fp2fflush(os);
                    268: }
                    269:
                    270: void oxfdSendCmoInt32(int fd,int k)
                    271: {
                    272:   char data[4*2];
                    273:   *((int *)&data[0]) = htonl(CMO_INT32);
                    274:   *((int *)&data[4]) = htonl(k);
                    275:   write(fd,data,4*2);
                    276:   fflush((FILE *)NULL);
                    277: }
                    278: void oxSendCmoInt32(ox_stream os,int k)
                    279: {
                    280:   char data[4*2];
                    281:   *((int *)&data[0]) = htonl(CMO_INT32);
                    282:   *((int *)&data[4]) = htonl(k);
                    283:   fp2write(os,data,4*2);
                    284:   fp2fflush(os);
                    285: }
                    286: void oxfdSendCmoString(int fd,char *s)
                    287: {
                    288:   char data[4*2];
                    289:   int n;
                    290:   if (s == NULL) n = 0;
                    291:   else {
                    292:     n = strlen(s);
                    293:   }
                    294:   *((int *)&data[0]) = htonl(CMO_STRING);
                    295:   *((int *)&data[4]) = htonl(n);
                    296:   write(fd,data,4*2);
                    297:   if (s != NULL) {
                    298:     write(fd,s,n);
                    299:   }
                    300:   fflush((FILE *)NULL);
                    301: }
                    302:
                    303: void oxSendCmoString(ox_stream os,char *s)
                    304: {
                    305:   char data[4*2];
                    306:   int n;
                    307:   if (s == NULL) n = 0;
                    308:   else {
                    309:     n = strlen(s);
                    310:   }
                    311:   *((int *)&data[0]) = htonl(CMO_STRING);
                    312:   *((int *)&data[4]) = htonl(n);
                    313:   fp2write(os,data,4*2);
                    314:   if (s != NULL) {
                    315:     fp2write(os,s,n);
                    316:   }
                    317:   fp2fflush(os);
                    318: }
                    319:
                    320:
                    321:
                    322: void oxReqPushString(ox_stream os, char *s)
                    323: {
                    324:   oxSendOXheader(os,OX_DATA,SerialOX++);
                    325:   oxSendCmoString(os,s);
                    326: }
                    327:
                    328: void oxSendResultOfControlInt32(int fd,int i)
                    329: {
                    330:   char data[4*2];
                    331:   oxfdSendOXheader(fd,OX_DATA,SerialOX++);
                    332:   *((int *)&data[0]) = htonl(CMO_INT32);
                    333:   *((int *)&data[4]) = htonl(i);
                    334:   write(fd,data,4*2);
                    335:   fflush((FILE *)NULL);
                    336: }
                    337:
                    338: void oxSendResultOfControl(int fd)
                    339: {
                    340:   char data[4*1];
                    341:   oxfdSendOXheader(fd,OX_DATA,SerialOX++);
                    342:   *((int *)&data[0]) = htonl(CMO_NULL);
                    343:   write(fd,data,4*1);
                    344:   fflush((FILE *)NULL);
                    345: }
                    346:
                    347:
                    348:
                    349: void oxSendMathCap(ox_stream os,struct mathCap *mathcap)
                    350: {
1.4       takayama  351:   int i,n,infosize,ncmo;
1.24      takayama  352:   struct object mathinfo = OINIT;
1.1       maekawa   353:   /* printf("ox sending mathcap\n"); fflush(stdout); */
                    354:   mathinfo = *((struct object *)(mathcap->infop));
                    355:   infosize = getoaSize(mathinfo);
                    356:
                    357:   oxSendInt32(os,CMO_MATHCAP);
                    358:
                    359:   oxSendInt32(os,CMO_LIST);
                    360:   oxSendInt32(os,3);
                    361:
                    362:   /* [0] */
                    363:   oxSendInt32(os,CMO_LIST);
                    364:   oxSendInt32(os,infosize);
                    365:   oxSendCmoInt32(os,KopInteger(getoa(mathinfo,0)));
                    366:   for (i=1; i<infosize; i++) {
                    367:     oxSendCmoString(os,KopString(getoa(mathinfo,i)));
                    368:   }
                    369:
                    370:   /* [1]  */
                    371:   oxSendInt32(os,CMO_LIST);
                    372:   oxSendInt32(os,mathcap->smSize);
                    373:   n = mathcap->smSize;
                    374:   for (i=0; i<n; i++) {
                    375:     oxSendCmoInt32(os,(mathcap->sm)[i]);
                    376:   }
                    377:
                    378:   /* [2] */
                    379:   oxSendInt32(os,CMO_LIST);
1.4       takayama  380:   n = mathcap->oxSize;
                    381:   oxSendInt32(os,n);
1.1       maekawa   382:
                    383:   oxSendInt32(os,CMO_LIST);
1.4       takayama  384:   oxSendInt32(os,2);
1.1       maekawa   385:   for (i=0; i<n; i++) {
1.4       takayama  386:     /* OX_DATA_xxx */
1.1       maekawa   387:     oxSendCmoInt32(os,(mathcap->ox)[i]);
1.4       takayama  388:     /* OX_DATA_xxx tags. In case of CMO, it is CMO tags. */
                    389:     oxSendInt32(os,CMO_LIST);
                    390:     oxSendInt32(os,mathcap->n);
                    391:     ncmo = mathcap->n;
                    392:     for (i=0; i<ncmo; i++) {
                    393:       oxSendCmoInt32(os,(mathcap->cmo)[i]);
                    394:       /* printf("i=%d %d, ",i,(mathcap->cmo)[i]); */
                    395:     }
1.1       maekawa   396:   }
                    397:   /* printf("\n"); fflush(stdout); */
                    398: }
                    399:
                    400: void oxReqMathCap(ox_stream os) {
                    401:   oxSendOXheader(os,OX_COMMAND,SerialOX++);
                    402:   oxSendInt32(os,SM_mathcap);
                    403:   fp2fflush(os);
                    404: }
                    405:
                    406: void oxReqSetMathCap(ox_stream os,struct mathCap *mathcap) {
                    407:   oxSendOXheader(os,OX_DATA,SerialOX++);
                    408:   oxSendMathCap(os,mathcap);
                    409:   oxSendOXheader(os,OX_COMMAND,SerialOX++);
                    410:   oxSendInt32(os,SM_setMathCap);
                    411:   fp2fflush(os);
                    412: }
                    413: void oxReqPops(ox_stream os,int n) {
                    414:   oxSendOXheader(os,OX_DATA,SerialOX++);
                    415:   oxSendCmoInt32(os,n);
                    416:   oxSendOXheader(os,OX_COMMAND,SerialOX++);
                    417:   oxSendInt32(os,SM_pops);
                    418:   fp2fflush(os);
                    419: }
                    420: void oxReqSetName(ox_stream os,char *s) {
                    421:   oxSendOXheader(os,OX_DATA,SerialOX++);
                    422:   oxSendCmoString(os,s);
                    423:   oxSendOXheader(os,OX_COMMAND,SerialOX++);
                    424:   oxSendInt32(os,SM_setName);
                    425:   fp2fflush(os);
                    426: }
                    427: void oxReqEvalName(ox_stream os,char *s) {
                    428:   oxSendOXheader(os,OX_DATA,SerialOX++);
                    429:   oxSendCmoString(os,s);
                    430:   oxSendOXheader(os,OX_COMMAND,SerialOX++);
                    431:   oxSendInt32(os,SM_evalName);
                    432:   fp2fflush(os);
                    433: }
                    434:
                    435: void oxReqExecuteStringByLocalParser(ox_stream os,char *s)
                    436: {
                    437:   oxSendOXheader(os,OX_DATA,SerialOX++);
                    438:   oxSendCmoString(os,s);
                    439:   oxSendOXheader(os,OX_COMMAND,SerialOX++);
                    440:   oxSendInt32(os,SM_executeStringByLocalParser);
                    441:   fp2fflush(os);
                    442: }
                    443:
                    444: void oxReqExecuteFunction(ox_stream os,char *s)
                    445: {
                    446:   oxSendOXheader(os,OX_DATA,SerialOX++);
                    447:   oxSendCmoString(os,s);
                    448:   oxSendOXheader(os,OX_COMMAND,SerialOX++);
                    449:   oxSendInt32(os,SM_executeFunction);
                    450:   fp2fflush(os);
                    451: }
                    452:
1.20      takayama  453: void oxReqExecuteFunctionWithOptionalArgument(ox_stream os,char *s)
                    454: {
                    455:   oxSendOXheader(os,OX_DATA,SerialOX++);
                    456:   oxSendCmoString(os,s);
                    457:   oxSendOXheader(os,OX_COMMAND,SerialOX++);
                    458:   oxSendInt32(os,SM_executeFunctionWithOptionalArgument);
                    459:   fp2fflush(os);
                    460: }
                    461:
1.1       maekawa   462:
                    463: void oxReqPopString(ox_stream os)
                    464: {
                    465:   oxSendOXheader(os,OX_COMMAND,SerialOX++);
                    466:   oxSendInt32(os,SM_popString);
                    467:   fp2fflush(os);
                    468: }
                    469:
                    470: void oxReqSingleOperand(ox_stream os,int smtag)
                    471: {
                    472:   oxSendOXheader(os,OX_COMMAND,SerialOX++);
                    473:   oxSendInt32(os,smtag);
                    474:   fp2fflush(os);
                    475: }
                    476:
                    477:
                    478: void oxReqControlResetConnection(int fd) {
                    479:   oxfdSendOXheader(fd,OX_COMMAND,SerialOX++);
                    480:   oxfdSendInt32(fd,SM_control_reset_connection);
                    481:   fflush(NULL);
                    482: }
                    483:
                    484: void oxReqControlKill(int fd) {
                    485:   oxfdSendOXheader(fd,OX_COMMAND,SerialOX++);
                    486:   oxfdSendInt32(fd,SM_control_kill);
                    487:   fflush(NULL);
                    488: }
                    489:
                    490: void oxReqPopCMO(ox_stream os) {
                    491:   oxSendOXheader(os,OX_COMMAND,SerialOX++);
                    492:   oxSendInt32(os,SM_popCMO);
                    493:   fp2fflush(os);
                    494: }
                    495:
                    496:
                    497: int oxGetResultOfControlInt32(int fd) {
                    498:   int k; int sss;
1.5       takayama  499:   SET_MYERROROUT;
1.1       maekawa   500:   k = oxfdGetOXheader(fd,&sss);
                    501:   if (k != OX_DATA) {
                    502:     fprintf(MyErrorOut,"oxGetResultOfControlInt32: wrong header.");
                    503:     return(-1);
                    504:   }
                    505:   k = oxfdGetInt32(fd); /* CMO_INT32 */
                    506:   k = oxfdGetInt32(fd);
                    507:   return(k);
                    508: }
                    509:
                    510: int oxclientMultiSelect(oxclientp clients[],int dataready[],
1.9       takayama  511:                         int controlready[], int size, int t)
1.1       maekawa   512: {
                    513:   int i, ddd;
                    514:   int fd;
                    515:   int humanfd = 0;
                    516:   fd_set readfds;
                    517:   struct timeval timeout;
                    518:
1.5       takayama  519:   SET_MYERROROUT;
1.1       maekawa   520:   /** printf("(1)"); fflush(NULL); */
                    521:   FD_ZERO(&readfds);
                    522:   timeout.tv_sec = 0;
                    523:   timeout.tv_usec = (long) t;
                    524:
                    525:   ddd = 0;  fd = 0;
                    526:   for (i=0; i<size; i++) {
                    527:     dataready[i] = controlready[i] = 0;
                    528:   }
                    529:   for (i=0; i<size; i++) {
                    530:     if (clients[i]->humanio) {
                    531:       fd = (fd<humanfd?humanfd:fd);
                    532:       FD_SET(humanfd,&readfds);
                    533:       if (oxSocketSelect0(humanfd,0)) {
1.9       takayama  534:         ddd = dataready[i] = 1; controlready[i] = 0;
1.1       maekawa   535:       }else{
1.9       takayama  536:         dataready[i] = 0; controlready[i] = 0;
1.1       maekawa   537:       }
                    538:     }else{
1.9       takayama  539:       if (clients[i]->controlport < 0) { /* For RFC_101 */
                    540:         controlready[i] = 0;
                    541:       }else{
                    542:         fd = (fd<clients[i]->controlfd?clients[i]->controlfd:fd);
                    543:         FD_SET(clients[i]->controlfd,&readfds);
                    544:         if (oxSocketSelect0(clients[i]->controlfd,0)) {
                    545:           ddd = controlready[i] = 1;
                    546:         }else{
                    547:           controlready[i] = 0;
                    548:         }
                    549:       }
1.1       maekawa   550:       if (clients[i]->datafp2 != NULL) {
1.9       takayama  551:         fd = (fd<clients[i]->datafp2->fd?clients[i]->datafp2->fd:fd);
                    552:         FD_SET(clients[i]->datafp2->fd,&readfds);
                    553:         if (fp2select(clients[i]->datafp2,0)) {
                    554:           ddd = dataready[i] = 1;
                    555:         }else{
                    556:           dataready[i] = 0;
                    557:         }
1.1       maekawa   558:       }else{
1.9       takayama  559:         dataready[i] = 0;
1.1       maekawa   560:       }
                    561:     }
                    562:   }
                    563:   if (t > 0 ) {
                    564:     if (ddd) return(1);
                    565:     if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) {
                    566:       fprintf(MyErrorOut,"error");
                    567:       return(-1);
                    568:     }
                    569:     return(oxclientMultiSelect(clients, dataready, controlready,size,0));
                    570:   }else if (t == 0) {
                    571:     return(ddd);
                    572:   }else {
                    573:     /** printf("(2)"); fflush(NULL); */
                    574:     if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL)<0) {
                    575:       fprintf(MyErrorOut,"error");
                    576:       return(-1);
                    577:     }
                    578:     /** printf("(3)"); fflush(NULL); */
                    579:     return(oxclientMultiSelect(clients, dataready, controlready,size,0));
                    580:   }
                    581: }
                    582:
                    583: int oxGetControl(oxclientp client)
1.9       takayama  584:      /* synchronized. */
1.1       maekawa   585: {
                    586:   int ans;
                    587:   ox_stream os;
                    588:   switch (client->cstate) {
                    589:   case 1:
                    590:     ans = oxGetResultOfControlInt32(client->controlfd);
                    591:     client->cstate = 0;
                    592:     return(ans);
                    593:   default:
                    594:     fprintf(MyErrorOut,"oxGet: unknown cstate.\n");
                    595:     client->cstate = -1;
                    596:     return(-1);
                    597:   }
                    598:
                    599:   return(-1);
                    600: }
                    601:
                    602: int oxInitClient(oxclientp client)
                    603: {
                    604:   client->datafp2 = NULL;
                    605:   client->dataport = 0;
                    606:   client->controlport = 0;
                    607:   client->controlfd = 0;
                    608:   client->humanio = 0;
                    609:   client->dstate = 0;
                    610:   client->cstate = 0;
                    611:   client->id = -1;
                    612:   client->mathcapObjp = NULL;
                    613:   client->controlByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
                    614:   client->engineByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
1.15      takayama  615:   client->engineID = -1;
1.1       maekawa   616:   return(0);
                    617: }
                    618:
                    619: int oxIsThereErrorClient(oxclientp client) {
                    620:   if (client == NULL) return(1);
                    621:   if (client->dstate == -1) return(1);
                    622:   if (client->cstate == -1) return(1);
                    623:   return(0);
                    624: }
                    625:
1.23      takayama  626: oxclientp oxCreateClient(char *sname,int portStream,int portControl,
                    627:                          char *passControl, char *passData)
1.9       takayama  628:      /* you also need to change oxCreateClient2. */
1.1       maekawa   629: {
                    630:   int v = 0;
                    631:   int fdControl = -1;
                    632:   int fdStream = -1;
                    633:   oxclientp client;
                    634:   int controlByteOrder, engineByteOrder;
                    635:   v = !Quiet;
                    636:   if (portControl != -1) {
                    637:     fdControl = socketConnect(sname,portControl);
                    638:     if (v) fprintf(stderr,"\nControl port %d : Connected.\n",portControl);
                    639:   }
                    640:   if (portStream != -1) {
                    641:     sleep(1); /* wait */
                    642:     fdStream = socketConnect(sname,portStream);
                    643:     if (v) fprintf(stderr,"\nStream port %d : Connected.\n",portStream);
                    644:   }
                    645:
                    646:   if (fdStream == -1 || fdControl == -1) {
                    647:     fprintf(stderr,"\nOpen error in oxCreateClient.\n");
                    648:     return(NULL);
1.23      takayama  649:   }
                    650:
                    651:   if (passControl != NULL) {
                    652:     if (v) fprintf(stderr,"Sending password %s for the control channel.\n",
                    653:                    passControl);
                    654:     if (write(fdControl,passControl,strlen(passControl)+1) < 0) {
                    655:       fprintf(stderr,"oxCreateClient(): failed to send passControl.\n");
                    656:       return(NULL);
                    657:     }
                    658:   }
                    659:   if (passData != NULL) {
                    660:     if (v) fprintf(stderr,"Sending password %s for the data channel.\n",
                    661:                    passData);
                    662:     if (write(fdStream,passData,strlen(passData)+1) < 0) {
                    663:       fprintf(stderr,"oxCreateClient(): failed to send passData.\n");
                    664:       return(NULL);
                    665:     }
1.1       maekawa   666:   }
                    667:
                    668:   controlByteOrder = oxSetByteOrder(fdControl);
                    669:   if (v) fprintf(stderr,"Byte order for control process is %s.\n",
1.9       takayama  670:                  (controlByteOrder == 0? "network byte order":
                    671:                   (controlByteOrder == 1? "little indican":
                    672:                    "big indian")));
1.1       maekawa   673:   engineByteOrder = oxSetByteOrder(fdStream);
                    674:   if (v) fprintf(stderr,"Byte order for engine process is %s.\n",
1.9       takayama  675:                  (engineByteOrder == 0? "network byte order":
                    676:                   (engineByteOrder == 1? "little indican":
                    677:                    "big indian")));
1.1       maekawa   678:
                    679:   client = (oxclientp) mymalloc(sizeof(oxclient));
                    680:   oxInitClient(client);
                    681:   client->datafp2 = fp2open(fdStream);
                    682:   if (client->datafp2 == NULL) {
                    683:     fprintf(stderr,"oxCreateClient(): fp2open(fd) failed.\n");
                    684:     return(NULL);
                    685:   }
                    686:   client->dataport = portStream;
                    687:   client->controlport = portControl;
                    688:   client->controlfd = fdControl;
1.13      takayama  689:   client->id = oxGetClientID();
1.1       maekawa   690:   client->type = CLIENT_SOCKET; /* socket */
                    691:   client->engineByteOrder = engineByteOrder;
                    692:   client->controlByteOrder = controlByteOrder;
                    693:   return(client);
                    694: }
                    695:
                    696: oxclientp oxCreateClientFile(char *fname,char *mode,char *controlName,char *cmode)
                    697: {
                    698:   static int clnum = 0x8000;
                    699:   int v = 0;
                    700:   int fdControl = -1;
                    701:   int fdStream = -1;
                    702:   oxclientp client;
                    703:   v = 1;
                    704:   if (strcmp(mode,"w") == 0) {
                    705:     fdStream = creat(fname,S_IWRITE|S_IREAD|S_IRGRP|S_IROTH);
                    706:     if (fdStream < 0) {
                    707:       fprintf(stderr,"\nCreat failed for %s\n",fname); return(NULL);
                    708:     }
                    709:   }else if (strcmp(mode,"r")==0) {
                    710:     fdStream = open(fname,O_RDONLY);
                    711:     if (fdStream < 0) {
                    712:       fprintf(stderr,"\nOpen failed for %s\n",fname); return(NULL);
                    713:     }
                    714:   }else {
                    715:     fprintf(stderr,"\nThe mode %s is not supported.\n",mode); return(NULL);
                    716:   }
                    717:
                    718:   if (strcmp(cmode,"w") == 0) {
                    719:     fdControl = creat(controlName,S_IWRITE|S_IREAD|S_IRGRP|S_IROTH);
                    720:     if (fdControl < 0) {
                    721:       fprintf(stderr,"\nCreat failed for %s\n",controlName); return(NULL);
                    722:     }
                    723:   }else if (strcmp(cmode,"r")==0) {
                    724:     fdControl = open(controlName,O_RDONLY);
                    725:     if (fdControl < 0) {
                    726:       fprintf(stderr,"\nOpen failed for %s\n",controlName); return(NULL);
                    727:     }
                    728:   }else if (strcmp(cmode,"rw")==0) {
                    729:     fdControl = open(controlName,O_RDWR);
                    730:     if (fdControl < 0) {
                    731:       fprintf(stderr,"\nOpen failed for %s\n",controlName); return(NULL);
                    732:     }
                    733:   }else {
                    734:     fprintf(stderr,"\nThe mode %s is not supported.\n",cmode); return(NULL);
                    735:   }
                    736:
                    737:
                    738:   client = (oxclientp) mymalloc(sizeof(oxclient));
                    739:   oxInitClient(client);
                    740:   client->datafp2 = fp2open(fdStream);
                    741:   if (client->datafp2 == NULL) {
                    742:     fprintf(stderr,"oxCreateClientFile(): fp2open(fd) failed.\n");
                    743:     return(NULL);
                    744:   }
                    745:   client->dataport = 0;
                    746:   client->controlport = 0;
                    747:   client->controlfd = fdControl;
                    748:   client->id = clnum; clnum++;
                    749:   client->type = CLIENT_FILE;
                    750:   client->engineByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
                    751:   client->controlByteOrder = OX_BYTE_NETWORK_BYTE_ORDER;
                    752:   return(client);
                    753: }
                    754:
                    755: void oxSendOXheader_generic(int type,int fd,ox_stream ox,
1.9       takayama  756:                             int k,int serial)
1.1       maekawa   757: {
                    758:   static int ss = 0;
                    759:   extern int UseOXPacketSerial;
                    760:   if (serial >= 0) ss = serial;
                    761:   else ss++;
                    762:   if (ss < 0) ss=0;
                    763:   if (type == 0) { /* fd */
                    764:     oxfdSendInt32(fd,k);
                    765:     if (UseOXPacketSerial) oxfdSendInt32(fd,ss);
                    766:   }else {
                    767:     oxSendInt32(ox,k);
                    768:     if (UseOXPacketSerial) oxSendInt32(ox,ss);
                    769:   }
                    770: }
                    771: void oxSendOXheader(ox_stream ostream,int k,int serial) {
                    772:   oxSendOXheader_generic(1,-1,ostream,k,serial);
                    773: }
                    774: void oxfdSendOXheader(int fd,int k,int serial) {
                    775:   oxSendOXheader_generic(0,fd,(ox_stream) NULL,k,serial);
                    776: }
                    777:
                    778: int oxfdGetOXheader(int fd,int *sss)
                    779: {
                    780:   char d[4];
                    781:   int i;
                    782:   int m;
                    783:
                    784:   for (i=0; i<4; i++) {
                    785:     d[i] = readOneByte(fd);
                    786:   }
                    787:   m = ntohl(* ( (int *)d));
                    788:   *sss = -1;
                    789:   if (UseOXPacketSerial) {
                    790:     for (i=0; i<4; i++) {
                    791:       d[i] = readOneByte(fd);
                    792:     }
                    793:     *sss = ntohl(* ( (int *)d));
                    794:   }
                    795:   return(m);
                    796: }
                    797:
                    798: int oxGetOXheader(ox_stream ostream,int *sss)
                    799: {
                    800:   char d[4];
                    801:   int m;
                    802:   int i;
                    803:
                    804:   unlockCtrlCForOx();  /* temporary unlock */
                    805:   while (fp2select(ostream,1000) == 0) ;
                    806:   restoreLockCtrlCForOx();
                    807:
                    808:   for (i=0; i<4; i++) {
                    809:     d[i] = fp2fgetc(ostream);
                    810:   }
                    811:   m = ntohl(* ( (int *)d));
                    812:   *sss = -1;
                    813:   if (UseOXPacketSerial) {
                    814:     for (i=0; i<4; i++) {
                    815:       d[i] = fp2fgetc(ostream);
                    816:     }
                    817:     *sss = ntohl(* ( (int *)d));
                    818:   }
                    819:   return(m);
                    820: }
                    821:
                    822:
                    823: oxWritePortFile(int func,int port,char *fname) {
                    824:   char name[1024];
                    825:   FILE *fp;
                    826:   strcpy(name,fname);
                    827:   if (func == 0) {
                    828:     strcat(name,".control");
                    829:     fp = fopen(name,"w");
                    830:     fprintf(fp,"%05d\n",port);
                    831:     fclose(fp);
                    832:   }else {
                    833:     strcat(name,".data");
                    834:     fp = fopen(name,"w");
                    835:     fprintf(fp,"%05d\n",port);
                    836:     fclose(fp);
                    837:   }
                    838: }
                    839: oxReadPortFile(int func,char *fname) {
                    840:   int port = 0;
                    841:   char name[1024];
                    842:   FILE *fp;
                    843:   strcpy(name,fname);
                    844:   if (func == 0) {
                    845:     strcat(name,".control");
                    846:     fp = fopen(name,"r");
                    847:     fscanf(fp,"%d",&port);
                    848:     fclose(fp);
                    849:   }else {
                    850:     strcat(name,".data");
                    851:     fp = fopen(name,"r");
                    852:     fscanf(fp,"%d",&port);
                    853:     fclose(fp);
                    854:   }
                    855:   return(port);
                    856: }
                    857: char *oxGenPortFile(void) {
                    858:   char *fname;
                    859:   time_t tt;
                    860:   char sstime[512];
                    861:
                    862:   fname = (char *)malloc(1024*sizeof(char));
                    863:   strcpy(fname,getenv("HOME"));
                    864:   strcat(fname,"/.ox.");
                    865:   tt = time(NULL);
                    866:   sprintf(sstime,"%ld",(long) tt);
                    867:   strcat(fname,sstime);
                    868:   if (fname[strlen(fname)-1] == '\n') {
                    869:     fname[strlen(fname)-1] = '\0';
                    870:   }
                    871:   /* fprintf(stderr,"OxPortFileName=%s\n",fname); */
                    872:   OxPortFileName = fname;
                    873:   return(fname);
                    874: }
                    875: int oxRemovePortFile(void) {
                    876:   char fname[1024];
                    877:   FILE *fp;
1.5       takayama  878:   SET_MYERROROUT;
1.1       maekawa   879:   strcpy(fname,OxPortFileName);
                    880:   strcat(fname,".control");
                    881:   if ((fp=fopen(fname,"r")) == NULL) {
                    882:   }{
                    883:     fclose(fp);
                    884:     if (unlink(fname)) {
                    885:       fprintf(MyErrorOut,"fail unlink.\n");
                    886:     }
                    887:
                    888:   }
                    889:   strcpy(fname,OxPortFileName);
                    890:   strcat(fname,".data");
                    891:   if ((fp=fopen(fname,"r")) == NULL) {
                    892:   }{
                    893:     fclose(fp);
                    894:     if (unlink(fname)) {
                    895:       fprintf(MyErrorOut,"fail unlink.\n");
                    896:     }
                    897:   }
                    898: }
                    899:
                    900: char *oxGenPass(void) {
1.3       takayama  901:   static int seed = 0;
1.1       maekawa   902:   long p;
                    903:   char *s;
1.21      takayama  904:   int i,n;
1.3       takayama  905:   if (seed == 0) {
                    906:     seed = (int) time(NULL) + (int) &p;
                    907:     srandom((unsigned int) seed);
                    908:   }
1.21      takayama  909:   s = (char *)malloc(128*sizeof(char));
                    910:   if (s == NULL) { fprintf(stderr,"No more memory.\n"); return(s); }
                    911:   n = (((int) s) + (int) time(NULL)) % 100;
                    912:   for (i=0; i < n ; i++) random();
1.1       maekawa   913:   p = random();
                    914:   sprintf(s,"%ld",p);
                    915:   return(s);
                    916: }
                    917:
                    918:
                    919: static void cancelConnection() {
1.12      takayama  920: #if defined(__CYGWIN__)
                    921:   extern sigjmp_buf MyEnv_oxmisc;
                    922: #else
1.1       maekawa   923:   extern jmp_buf MyEnv_oxmisc;
1.12      takayama  924: #endif
1.1       maekawa   925:   signal(SIGALRM,SIG_IGN);
                    926:   fprintf(stderr,"Time out in TCP/IP connection.\n");
1.12      takayama  927: #if defined(__CYGWIN__)
1.29    ! takayama  928:   MYSIGLONGJMP(MyEnv_oxmisc,1);
1.12      takayama  929: #else
1.29    ! takayama  930:   MYLONGJMP(MyEnv_oxmisc,1);
1.12      takayama  931: #endif
1.1       maekawa   932: }
                    933:
                    934: oxclientp oxCreateClient2(int fdstream,int portStream,
1.22      takayama  935:                           int fdcontrol,int portControl,int ipmask,
                    936:                           char *passControl, char *passData)
1.1       maekawa   937: {
                    938:   int v = 0;
                    939:   int fdControl = -1;
                    940:   int fdStream = -1;
                    941:   int m;
                    942:
                    943:   char *s;
                    944:   oxclientp client;
1.12      takayama  945: #if defined(__CYGWIN__)
                    946:   extern sigjmp_buf MyEnv_oxmisc;
                    947: #else
                    948:   extern jmp_buf MyEnv_oxmisc;
                    949: #endif
1.1       maekawa   950:   int controlByteOrder, engineByteOrder;
                    951:
                    952:   v = !Quiet;
1.12      takayama  953: #if defined(__CYGWIN__)
1.29    ! takayama  954:   if (MYSIGSETJMP(MyEnv_oxmisc,1)) {
1.12      takayama  955: #else
1.29    ! takayama  956:   if (MYSETJMP(MyEnv_oxmisc)) {
1.12      takayama  957: #endif
1.1       maekawa   958:     return(NULL);
                    959:   }else{
                    960:   }
1.11      takayama  961:   alarm((unsigned int) 20);  /* setup timeout. */
1.1       maekawa   962:   signal(SIGALRM,cancelConnection);
                    963:
                    964:   switch(ipmask) {
                    965:   case 0:/* only local */
                    966:     fdControl = socketAcceptLocal(fdcontrol);
                    967:     fdStream  = socketAcceptLocal(fdstream);
                    968:     break;
                    969:   default:/* any */
                    970:     fdControl = socketAccept(fdcontrol);
                    971:     fdStream  = socketAccept(fdstream);
                    972:     break;
                    973:   }
                    974:   if (v) fprintf(stderr,"\nControl port %d : Connected.\n",portControl);
                    975:   if (v) fprintf(stderr,"\nStream port %d : Connected.\n",portStream);
                    976:
                    977:   if (fdStream == -1 || fdControl == -1) {
1.16      takayama  978:     fprintf(stderr,"\nOpen error in oxCreateClient2.\n");
                    979:     fprintf(stderr,"fdStream=%d, fdControl=%d\n",fdStream,fdControl);
1.1       maekawa   980:     return(NULL);
                    981:   }
                    982:
1.6       takayama  983:   /* Authentication by password. */
1.22      takayama  984:   m = strlen(passControl)+strlen(passData);
1.10      takayama  985:   if (m > 0) {
                    986:     s = (char *)mymalloc(sizeof(char)*(m+1));
1.22      takayama  987:     m = strlen(passControl); s[0] = 0;
1.10      takayama  988:     read(fdControl,s,m+1); s[m] = '\0';
1.22      takayama  989:     if (strcmp(s,passControl) != 0) {
                    990:       fprintf(stderr,"s=%s, passControl=%s\n",s,passControl);
1.10      takayama  991:       fprintf(stderr,"oxCreateClient2(): password authentication failed for control channel.\n");
                    992:       close(fdControl);
                    993:       return(NULL);
                    994:     }
1.22      takayama  995:     m = strlen(passData); s[0] = 0;
1.10      takayama  996:     read(fdStream,s,m+1); s[m] = '\0';
1.22      takayama  997:     if (strcmp(s,passData) != 0) {
                    998:       fprintf(stderr,"s=%s, passData=%s\n",s,passData);
1.10      takayama  999:       fprintf(stderr,"oxCreateClient2(): password authentication failed for data channel.\n");
                   1000:       close(fdStream);
                   1001:       return(NULL);
                   1002:     }
1.1       maekawa  1003:   }
                   1004:   signal(SIGALRM,SIG_IGN);
                   1005:
                   1006:   controlByteOrder = oxSetByteOrder(fdControl);
                   1007:   if (v) fprintf(stderr,"Byte order for control process is %s.\n",
1.9       takayama 1008:                  (controlByteOrder == 0? "network byte order":
                   1009:                   (controlByteOrder == 1? "little indican":
                   1010:                    "big indian")));
1.1       maekawa  1011:   engineByteOrder = oxSetByteOrder(fdStream);
                   1012:   if (v) fprintf(stderr,"Byte order for engine process is %s.\n",
1.9       takayama 1013:                  (engineByteOrder == 0? "network byte order":
                   1014:                   (engineByteOrder == 1? "little indican":
                   1015:                    "big indian")));
1.1       maekawa  1016:
                   1017:
                   1018:   client = (oxclientp) mymalloc(sizeof(oxclient));
                   1019:   oxInitClient(client);
                   1020:   client->datafp2 = fp2open(fdStream);
                   1021:   if (client->datafp2 == NULL) {
                   1022:     fprintf(stderr,"oxCreateClient2(): fp2open(fd) failed.\n");
                   1023:     return(NULL);
                   1024:   }
                   1025:   client->dataport = portStream;
                   1026:   client->controlport = portControl;
                   1027:   client->controlfd = fdControl;
1.13      takayama 1028:   client->id = oxGetClientID();
1.1       maekawa  1029:   client->type = CLIENT_SOCKET; /* socket */
                   1030:   client->engineByteOrder = engineByteOrder;
                   1031:   client->controlByteOrder = controlByteOrder;
                   1032:   return(client);
                   1033: }
                   1034:
                   1035: int oxSetByteOrder(int fd) {
                   1036:   char data[1];
                   1037:   int peertype;
                   1038:   /* It is for client. read and next write. */
                   1039:   /* oxSocketSelect0(fd,10);  wait. */
                   1040:   read(fd,data,1);
                   1041:   peertype = (unsigned char) data[0];
                   1042:
                   1043:   /* We support only Network byte order */
                   1044:   data[0] = OX_BYTE_NETWORK_BYTE_ORDER;
                   1045:   write(fd,data,1);
                   1046:
                   1047:   return(OX_BYTE_NETWORK_BYTE_ORDER);
                   1048: }
                   1049:
1.17      takayama 1050: int oxTellMyByteOrder(int fdOut, int fdIn) {
1.1       maekawa  1051:   char data[1];
                   1052:   int peertype;
                   1053:   /* It is for server. read and next write. */
                   1054:
                   1055:   /* We support only Network byte order */
                   1056:   data[0] = OX_BYTE_NETWORK_BYTE_ORDER;
1.17      takayama 1057:   write(fdOut,data,1);
                   1058:   fsync(fdOut);  /* returns 0 if normal. Does it work for socket? */
1.1       maekawa  1059:
1.17      takayama 1060:   read(fdIn,data,1); /* Read pear's byte order */
1.1       maekawa  1061:
                   1062:   return(OX_BYTE_NETWORK_BYTE_ORDER);
                   1063: }
                   1064:
                   1065:
1.14      takayama 1066: struct object OxClientList[MAX_N_OF_CLIENT];
                   1067: int OxClientListn = 0;
                   1068:
                   1069: int oxGetClientID() {
                   1070:   extern struct object OxClientList[];
                   1071:   extern int OxClientListn;
                   1072:   extern struct object Nobj;
                   1073:   int i;
                   1074:   for (i=0; i<OxClientListn; i++) {
                   1075:        if ((OxClientList[i]).tag == Snull) {
                   1076:          return i;
                   1077:        }
                   1078:   }
                   1079:   i = OxClientListn;
                   1080:   (OxClientList[i]).tag = Snull;
                   1081:   if (OxClientListn < MAX_N_OF_CLIENT-1) {
                   1082:        OxClientListn++;
                   1083:        return i;
                   1084:   }else{
                   1085:        fprintf(MyErrorOut,"oxGetClientID(): the client table is full. Returns ID = 0.\n");
                   1086:        return 0;
                   1087:   }
                   1088: }
1.1       maekawa  1089:
1.18      takayama 1090: char *oxFIDtoStr(int id) {
                   1091:   switch( id ) {
                   1092:   case SM_mathcap:
                   1093:     return "SM_mathcap"; break;
                   1094:   case SM_setMathCap:
                   1095:     return "SM_setMathCap"; break;
                   1096:   case SM_pops:
                   1097:     return "SM_pops"; break;
                   1098:   case SM_getsp:
                   1099:     return "SM_getsp"; break;
                   1100:   case SM_dupErrors:
                   1101:     return "SM_dupErrors"; break;
                   1102:   case SM_pushCMOtag:
                   1103:     return "SM_pushCMOtag"; break;
                   1104:   case SM_setName:
                   1105:     return "SM_setName"; break;
                   1106:   case SM_evalName:
                   1107:     return "SM_evalName"; break;
                   1108:   case SM_executeStringByLocalParser:
                   1109:     return "SM_executeStringByLocalParser"; break;
                   1110:   case SM_executeFunction:
                   1111:     return "SM_executeFunction"; break;
1.20      takayama 1112:   case SM_executeFunctionWithOptionalArgument:
                   1113:     return "SM_executeFunctionWithOptionalArgument"; break;
1.18      takayama 1114:   case SM_popCMO:
                   1115:     return "SM_popCMO"; break;
                   1116:   case SM_popString:
                   1117:     return "SM_popString"; break;
                   1118:   case SM_shutdown:
                   1119:     return "SM_shutdown"; break;
                   1120:   case SM_beginBlock:
                   1121:     return "SM_beginBlock"; break;
                   1122:   case SM_endBlock:
                   1123:     return "SM_endBlock"; break;
                   1124:   default:
                   1125:     return "Unknown to oxFIDtoStr"; break;
                   1126:   }
                   1127: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>