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

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

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