[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.28

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

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