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

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

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