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

Annotation of OpenXM/src/kan96xx/plugin/oxmisc2.c, Revision 1.28

1.28    ! takayama    1: /* $OpenXM: OpenXM/src/kan96xx/plugin/oxmisc2.c,v 1.27 2013/11/06 06:23:24 takayama Exp $ */
1.1       maekawa     2: #include <stdio.h>
1.26      ohara       3: #include <string.h>
1.28    ! takayama    4: #include <unistd.h>
1.1       maekawa     5: #include "ox_kan.h"
                      6: #include "oxmisc2.h"   /* This file requires sm1 object description. */
                      7: #include "cmo.h"
1.8       takayama    8:
1.1       maekawa     9: extern FILE *MyErrorOut;
1.6       takayama   10: #define SET_MYERROROUT { if (MyErrorOut == NULL) MyErrorOut=stdout; }
                     11: /* It is also defined in oxmisc.c */
                     12:
1.1       maekawa    13: extern int SerialOX; /* defined in SerialOX */
                     14:
                     15: extern int OxVersion;
                     16:
                     17: int DebugMathCap = 1;
                     18:
                     19:
                     20:
                     21: int oxGet(oxclientp client, struct object *op,int *isObj)
1.12      takayama   22:      /* This method should be synchronized. */
                     23:      /* oxGet is a function for client. */
1.1       maekawa    24: {
                     25:   int ans;
                     26:   ox_stream os;
                     27:   int m;
1.25      takayama   28:   struct object rob = OINIT;
1.1       maekawa    29:   int sss;  /* Serial number of the recieved packet. */
                     30:   *isObj = 0;
                     31:   op->tag = Snull;
                     32:   os = client->datafp2;
                     33:   switch(client->dstate) {
                     34:   case DSTATE_ANY:
                     35:     m = oxGetOXheader(os,&sss);
                     36:     switch(m) {
                     37:     case OX_DATA:
                     38:       client->dstate = DSTATE_WAIT_OX_DATA;
                     39:       return(oxGet(client,op,isObj));
                     40:     case OX_SYNC_BALL:
                     41:       client->dstate = DSTATE_ANY;
                     42:       return(OX_SYNC_BALL);
                     43:     default:
                     44:       errorOxmisc2("oxGet: cannot handle this tag.\n");
                     45:       client->dstate = DSTATE_ERROR;
                     46:       return(-1);
                     47:     }
                     48:     break;
                     49:   case DSTATE_FIRST_SYNC:  /* waiting the first sync ball */
                     50:     /* I need to clear the buffer?? */
                     51:     oxWaitSyncBall(os);
                     52:     client->dstate = DSTATE_ANY;
                     53:     oxSendSyncBall(os);
                     54:     return(OX_SYNC_BALL);
                     55:     break;
                     56:   case DSTATE_WAIT_OX_DATA:  /* waiting a cmo data. */
                     57:     *op = cmoObjectFromStream2(client->datafp2);
                     58:     client->dstate = DSTATE_ANY;
                     59:     *isObj = 1;
                     60:     return(0);
                     61:     break;
                     62:   case DSTATE_ERROR:
                     63:     client->dstate = DSTATE_ERROR;
                     64:     errorOxmisc2("oxGet: dstate == DSTATE_ERROR (error state)\n");
                     65:     return(-1);
                     66:   default:
                     67:     client->dstate = DSTATE_ERROR;
                     68:     errorOxmisc2("oxGet: Unknown state number.");
                     69:   }
                     70:
                     71:   return(-1);
                     72: }
                     73:
                     74: int oxGetFromControl(oxclientp client)
                     75: {
                     76:   int ans = -1;
1.7       takayama   77:   AbortIfRFC_101(client);
1.1       maekawa    78:   if (client->cstate != -1) {
                     79:     ans = oxGetResultOfControlInt32(client->controlfd);
                     80:     if (ans != -1) {    client->cstate = 0; }
                     81:     else {client->cstate = -1; }
                     82:   }
                     83:   return(ans);
                     84: }
                     85:
                     86: int oxReq(oxclientp client,int func,struct object ob)
                     87: {
                     88:   struct object *ob1p;
1.6       takayama   89:   SET_MYERROROUT;
1.1       maekawa    90:   /* request to the control channel */
                     91:   if (func == SM_control_reset_connection ||
                     92:       func == SM_control_kill) {
1.12      takayama   93:     AbortIfRFC_101(client);
1.1       maekawa    94:     switch(func) {
                     95:     case SM_control_reset_connection:
                     96:       oxReqControlResetConnection(client->controlfd);
1.9       takayama   97:       client->cstate = 0;
1.1       maekawa    98:       client->dstate = DSTATE_FIRST_SYNC;
                     99:       break;
                    100:     case SM_control_kill:
                    101:       oxReqControlKill(client->controlfd);
                    102:       client->cstate = 0;
                    103:       client->dstate = DSTATE_ANY;
                    104:       break;
                    105:     }
                    106:     fflush(NULL);
                    107:     return(0);
                    108:   }
                    109:
                    110:   /* request to the data channel */
                    111:   if (client->dstate != DSTATE_ANY) {
                    112:     errorOxmisc2("oxReq: client->dstate != DSTATE_ANY, data channel is not ready to send data.\n");
                    113:     return(-1);
                    114:   }
                    115:   switch(func) {
                    116:   case SM_DUMMY_sendcmo:
                    117:     if (!cmoCheckMathCap(ob,(struct object *)client->mathcapObjp)) {
                    118:       errorOxmisc2("oxReq: your peer does not understand this cmo.\n");
                    119:       return(-1);
                    120:     }
                    121:     oxSendOXheader(client->datafp2,OX_DATA,SerialOX++);
                    122:     cmoObjectToStream2(ob,client->datafp2);
                    123:     client->dstate = DSTATE_ANY;
                    124:     break;
                    125:   case SM_sync_ball:
                    126:     oxSendSyncBall(client->datafp2);
                    127:     client->dstate = DSTATE_ANY; /*  We do not expect the sync ball.*/
                    128:     client->cstate = 0;          /* clear the cstate */
                    129:     break;
                    130:   case SM_popCMO:
                    131:     oxReqPopCMO(client->datafp2);
                    132:     client->dstate = DSTATE_ANY;
                    133:     break;
                    134:   case SM_mathcap:
                    135:     oxReqMathCap(client->datafp2);
                    136:     client->dstate = DSTATE_ANY;
                    137:     break;
                    138:   case SM_setMathCap:
                    139:     /* ob = [(mathcap-obj) [[version num, system name] [sm tags]
1.12      takayama  140:        ob1                        smtags
                    141:        oxtags      [[ox numbers, [cmo numbers]]]
                    142:        ob3         ob2 */
                    143:     /*     oxtags      [[OX_DATA, [cmo numbers]],[OX_DATA_LOCAL,[opt]],...]*/
1.1       maekawa   144:     {
1.25      takayama  145:       struct object ob1 = OINIT;
                    146:       struct object ob2 = OINIT;
                    147:       struct object ob3 = OINIT;
                    148:       struct object obm = OINIT;
                    149:       struct object smtags = OINIT;
                    150:       struct object oxtags = OINIT;
                    151:       struct object ox = OINIT;
1.12      takayama  152:       int n,i;
                    153:       struct mathCap mathcap;
1.1       maekawa   154:
1.12      takayama  155:       if (strcmp(KopString(getoa(ob,0)),"mathcap-object") != 0) {
                    156:         errorOxmisc2("data format error in oxReqSetMathCap");
                    157:         client->dstate = DSTATE_ANY;
                    158:         break;
                    159:       }
1.4       takayama  160:       obm = getoa(ob,1);
                    161:       ob1 = getoa(obm,0);
                    162:       smtags = getoa(obm,1);
                    163:       oxtags = getoa(obm,2);
                    164:       if (smtags.tag != Sarray || oxtags.tag != Sarray) {
1.12      takayama  165:         errorOxmisc2("data format error in oxReqSetMathCap");
1.4       takayama  166:       }
1.1       maekawa   167:       ob1p = (struct object *) sGC_malloc(sizeof(struct object));
                    168:       *ob1p = ob1;
                    169:       mathcap.infop = ob1p;
1.4       takayama  170:
                    171:       n = getoaSize(oxtags);
1.1       maekawa   172:       if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
                    173:       mathcap.oxSize = n;
                    174:       for (i=0; i<n; i++) {
1.12      takayama  175:         ox = getoa(oxtags,i);
                    176:         if (ox.tag != Sarray) {
                    177:           errorOxmisc2("Data format error of the third argument of mathcap.");
                    178:         }
                    179:         mathcap.ox[i] = KopInteger(getoa(ox,0));
                    180:         if (mathcap.ox[i] == OX_DATA) {
                    181:           if (getoaSize(ox) < 2) {
                    182:             errorOxmisc2("Data format error in an entry of the third argument of mathcap.");
                    183:           }
                    184:           ob2 = getoa(ox,1);
                    185:           if (ob2.tag != Sarray) {
                    186:             errorOxmisc2("Data format error in an entry of the third argument of mathcap.");
                    187:           }
                    188:           mathcap.n = getoaSize(ob2);
                    189:           if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
                    190:           for (i=0; i<mathcap.n; i++) {
                    191:             mathcap.cmo[i] = KopInteger(getoa(ob2,i));
                    192:           }
                    193:         }
1.1       maekawa   194:       }
                    195:
                    196:       n = getoaSize(smtags);
                    197:       if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
                    198:       mathcap.smSize = n;
                    199:       for (i=0; i<n; i++) {
1.12      takayama  200:         mathcap.sm[i] = KopInteger(getoa(smtags,i));
1.1       maekawa   201:       }
                    202:
                    203:       oxReqSetMathCap(client->datafp2,&mathcap);
                    204:       client->dstate = DSTATE_ANY;
                    205:     }
                    206:     break;
                    207:   case SM_pops:
                    208:     if (ob.tag != Sinteger) {
                    209:       errorOxmisc2("SM_pops : the argument must be an integer.");
                    210:       return(-1);
                    211:     }
                    212:     oxReqPops(client->datafp2, KopInteger(ob));
                    213:     client->dstate = DSTATE_ANY;
                    214:     break;
                    215:   case SM_executeStringByLocalParser:
                    216:     if (ob.tag != Sdollar) {
                    217:       errorOxmisc2("SM_executeStringByLocalParser : the argument must be a string.");
                    218:       return(-1);
                    219:     }
                    220:     oxReqExecuteStringByLocalParser(client->datafp2,KopString(ob));
                    221:     client->dstate = DSTATE_ANY;
                    222:     break;
                    223:   case SM_executeFunction:
                    224:     if (ob.tag != Sdollar) {
                    225:       errorOxmisc2("SM_executeFunction : the argument must be a string.");
                    226:       return(-1);
                    227:     }
                    228:     oxReqExecuteFunction(client->datafp2,KopString(ob));
1.22      takayama  229:     client->dstate = DSTATE_ANY;
                    230:     break;
                    231:   case SM_executeFunctionWithOptionalArgument:
                    232:     if (ob.tag != Sdollar) {
                    233:       errorOxmisc2("SM_executeFunctionWithOptionalArgument : the argument must be a string.");
                    234:       return(-1);
                    235:     }
                    236:     oxReqExecuteFunctionWithOptionalArgument(client->datafp2,KopString(ob));
1.1       maekawa   237:     client->dstate = DSTATE_ANY;
                    238:     break;
                    239:   case SM_popString:
                    240:     oxReqPopString(client->datafp2);
                    241:     client->dstate = DSTATE_ANY;
                    242:     break;
                    243:   case SM_evalName:
                    244:     if (ob.tag != Sdollar) {
                    245:       errorOxmisc2("SM_evalName : the argument must be a string.");
                    246:       return(-1);
                    247:     }
                    248:     oxReqEvalName(client->datafp2,KopString(ob));
                    249:     client->dstate = DSTATE_ANY;
                    250:     break;
                    251:   case SM_setName:
                    252:     if (ob.tag != Sdollar) {
                    253:       errorOxmisc2("SM_setName : the argument must be a string.");
                    254:       return(-1);
                    255:     }
                    256:     oxReqSetName(client->datafp2,KopString(ob));
                    257:     client->dstate = DSTATE_ANY;
                    258:     break;
                    259:   case SM_getsp:
                    260:     oxReqSingleOperand(client->datafp2,SM_getsp);
                    261:     client->dstate = DSTATE_ANY;
                    262:     break;
                    263:   case SM_dupErrors:
                    264:     oxReqSingleOperand(client->datafp2,SM_dupErrors);
1.21      takayama  265:     client->dstate = DSTATE_ANY;
                    266:     break;
                    267:   case SM_pushCMOtag:
                    268:     oxReqSingleOperand(client->datafp2,SM_pushCMOtag);
1.1       maekawa   269:     client->dstate = DSTATE_ANY;
                    270:     break;
                    271:   default:
                    272:     fprintf(MyErrorOut,"func=%d ",func);
                    273:     errorOxmisc2("This function is not implemented.");
                    274:     break;
                    275:   }
                    276:   fp2fflush(client->datafp2);
                    277:   return(0);
                    278: }
                    279:
                    280: struct object KoxCreateClient(struct object ip,
1.12      takayama  281:                               struct object portStream,
1.24      takayama  282:                               struct object portControl,struct object pass)
1.1       maekawa   283: {
1.25      takayama  284:   struct object rob = OINIT;
1.1       maekawa   285:   oxclientp client;
1.24      takayama  286:   char *passControl; char *passData;
1.25      takayama  287:   struct object tob = OINIT;
1.24      takayama  288:   passControl = NULL; passData = NULL;
1.1       maekawa   289:   rob.tag = Snull;
                    290:   if (ip.tag != Sdollar) {
                    291:     errorOxmisc2("KoxCreateClient(): The first argument must be a hostname given by a string.");
                    292:     return(rob);
                    293:   }
                    294:   if (portStream.tag == Sdollar) {
                    295:     client = oxCreateClientFile(KopString(ip),KopString(portStream),
1.12      takayama  296:                                 "/dev/null","w");
1.1       maekawa   297:     if (client == NULL) {
                    298:       errorOxmisc2("KoxCreateClient(): Open error.");
                    299:       return(rob);
                    300:     }
                    301:     rob = newObjectArray(N_OF_CLIENT_FIELDS);
                    302:     oxClientToObject(client,rob);
                    303:     return(rob);
                    304:   }
                    305:
                    306:   if (portStream.tag != Sinteger) {
                    307:     errorOxmisc2("KoxCreateClient(): The second argument must be a port number given in an integer.");
                    308:     return(rob);
                    309:   }
                    310:   if (portControl.tag != Sinteger) {
                    311:     errorOxmisc2("KoxCreateClient(): The third argument must be a port number given in an integer.");
                    312:     return(rob);
                    313:   }
1.24      takayama  314:   if (pass.tag == Sarray) {
                    315:     if (getoaSize(pass) < 2) {
                    316:          errorOxmisc2("KoxCreateClient(): the fourth argument --- pass must be an array of strings.");
                    317:          return rob;
                    318:        }
                    319:     tob = getoa(pass,0);
                    320:        if (tob.tag != Sdollar) {
                    321:          errorOxmisc2("KoxCreateClient(): the fourth argument --- pass must be an array of strings.");
                    322:          return rob;
                    323:        }
                    324:     passControl = KopString(tob);
                    325:     tob = getoa(pass,1);
                    326:        if (tob.tag != Sdollar) {
                    327:          errorOxmisc2("KoxCreateClient(): the fourth argument --- pass must be an array of strings.");
                    328:          return rob;
                    329:        }
                    330:     passData = KopString(tob);
                    331:   }
                    332:   client = oxCreateClient(KopString(ip),KopInteger(portStream),KopInteger(portControl),passControl,passData);
1.1       maekawa   333:   if (client == NULL) {
                    334:     errorOxmisc2("KoxCreateClient(): Open error.");
                    335:     return(rob);
                    336:   }
                    337:   rob = newObjectArray(N_OF_CLIENT_FIELDS);
                    338:   oxClientToObject(client,rob);
1.14      takayama  339:   oxClientListUpdate(rob);
1.1       maekawa   340:   return(rob);
                    341: }
                    342:
                    343: static int isItClientObject(struct object ob)
                    344: {
                    345:   int size,i;
                    346:   struct object ee[N_OF_CLIENT_FIELDS];
                    347:   if (ob.tag != Sarray) {
                    348:     return(0);
                    349:   }
                    350:   size = getoaSize(ob);
                    351:   if (size != N_OF_CLIENT_FIELDS) return(0);
                    352:   for (i=0; i<N_OF_CLIENT_FIELDS; i++) {
                    353:     ee[i] = getoa(ob,i);
                    354:   }
                    355:
                    356:   if (ee[0].tag != Sdollar) return(0);
                    357:   if (strcmp(KopString(ee[0]),"client")!=0) return(0);
                    358:
                    359:   if (ee[1].tag != Sfile) return(0);
                    360:   if (strcmp((ee[1]).lc.str,MAGIC2) != 0) return(0);
                    361:
                    362:   for (i=2; i<=9; i++) {
                    363:     if (ee[i].tag != Sinteger) return(0);
                    364:   }
                    365:   return(1);
                    366: }
                    367:
                    368:
                    369: struct object KoxIsThereErrorClient(struct object ob)
                    370: {
1.25      takayama  371:   struct object rob = OINIT;
1.1       maekawa   372:   int ans;
                    373:   int size;
                    374:   oxclient cc;
                    375:   rob.tag = Snull;
                    376:   if (!isItClientObject(ob)) {
                    377:     errorOxmisc2("KoxIsThereErrorClient(): the argument must be an array for client object.");
                    378:     return(rob);
                    379:   }
                    380:   if (oxObjectToClient(ob,&cc) == -1) return(KpoInteger(-1));
                    381:   ans = oxIsThereErrorClient(&cc);
                    382:   return(KpoInteger(ans));
                    383: }
                    384:
                    385: int oxClientToObject(oxclientp client,struct object rob)
                    386: {
1.25      takayama  387:   struct object ob = OINIT;
1.27      takayama  388:   if (client == NULL) return 0;
1.1       maekawa   389:   /* rob = newObjectArray(N_OF_CLIENT_FIELDS); */
                    390:   if (rob.tag != Sarray) {
                    391:     errorOxmisc2("oxClientToObject(): the second argument must be an array.");
                    392:     return(-1);
                    393:   }
                    394:   if (getoaSize(rob) != N_OF_CLIENT_FIELDS) {
                    395:     errorOxmisc2("oxClientToObject(): the second argument must be an array of size N_OF_CLIENT_FIELDS.");
                    396:     return(-1);
                    397:   }
                    398:
                    399:   ob = KpoString("client");
                    400:   putoa(rob,0,ob);
                    401:
                    402:   ob.tag = Sfile; ob.lc.str = MAGIC2; ob.rc.voidp = (void *)(client->datafp2);
                    403:   putoa(rob,1,ob);
                    404:
                    405:   putoa(rob,2,KpoInteger(client->dataport));
                    406:   putoa(rob,3,KpoInteger(client->controlfd));
                    407:   putoa(rob,4,KpoInteger(client->controlport));
                    408:   putoa(rob,5,KpoInteger(client->dstate));
                    409:   putoa(rob,6,KpoInteger(client->cstate));
                    410:   putoa(rob,7,KpoInteger(client->humanio));
                    411:   putoa(rob,8,KpoInteger(client->id));
                    412:   putoa(rob,9,KpoInteger(client->type));
                    413:   if (client->mathcapObjp == NULL) {
                    414:     putoa(rob,10,NullObject);
                    415:   }else{
                    416:     putoa(rob,10,*((struct object *)(client->mathcapObjp)));
                    417:   }
                    418:   putoa(rob,11,KpoInteger(client->engineByteOrder));
                    419:   putoa(rob,12,KpoInteger(client->controlByteOrder));
1.16      takayama  420:   putoa(rob,13,KpoInteger(client->engineID));
1.1       maekawa   421:   return(0);
                    422: }
                    423:
                    424: int oxObjectToClient(struct object ob,oxclientp cp)
                    425: {
1.25      takayama  426:   struct object ob1 = OINIT;
1.1       maekawa   427:   struct object *obp;
                    428:   if (cp == NULL) {
                    429:     errorOxmisc2("oxObjectToClient(): the second argument is NULL");
                    430:     return(-1);
                    431:   }
                    432:   if (!isItClientObject(ob)) {
                    433:     errorOxmisc2("oxObjectToClient(): the first argument is not client object.");
                    434:     oxInitClient(cp);
                    435:     return(-1);
                    436:   }
                    437:
                    438:   ob1 = getoa(ob,1);
                    439:   cp->datafp2 = (FILE2 *) (ob1.rc.voidp);
                    440:
                    441:   ob1 = getoa(ob,2);
                    442:   cp->dataport = KopInteger(ob1);
                    443:
                    444:   ob1 = getoa(ob,3);
                    445:   cp->controlfd = KopInteger(ob1);
                    446:
                    447:   ob1 = getoa(ob,4);
                    448:   cp->controlport = KopInteger(ob1);
                    449:
                    450:   ob1 = getoa(ob,5);
                    451:   cp->dstate = KopInteger(ob1);
                    452:
                    453:   ob1 = getoa(ob,6);
                    454:   cp->cstate = KopInteger(ob1);
                    455:
                    456:   ob1 = getoa(ob,7);
                    457:   cp->humanio = KopInteger(ob1);
                    458:
                    459:   ob1 = getoa(ob,8);
                    460:   cp->id = KopInteger(ob1);
                    461:
                    462:   ob1 = getoa(ob,9);
                    463:   cp->type = KopInteger(ob1);
                    464:
                    465:   ob1 = getoa(ob,10);
                    466:   if (ob1.tag == Snull) {
                    467:     cp->mathcapObjp = NULL;
                    468:   }else{
                    469:     obp = (struct object *) sGC_malloc(sizeof(struct object));
                    470:     *obp = ob1;
                    471:     cp->mathcapObjp = (void *)obp;
                    472:   }
                    473:   ob1 = getoa(ob,11);
                    474:   cp->engineByteOrder = KopInteger(ob1);
                    475:   ob1 = getoa(ob,12);
                    476:   cp->controlByteOrder = KopInteger(ob1);
1.16      takayama  477:
                    478:   ob1 = getoa(ob,13);
                    479:   cp->engineID = KopInteger(ob1);
1.1       maekawa   480:
                    481:
                    482:   return(0);
                    483: }
                    484:
                    485: struct object KoxReq(struct object client,
1.12      takayama  486:                      struct object func,
                    487:                      struct object ob1)
1.1       maekawa   488: {
                    489:   int ans;
                    490:   static oxclientp cc1 = NULL;
1.25      takayama  491:   struct object rob = OINIT;
1.1       maekawa   492:   rob.tag = Snull;
                    493:   if (cc1 == NULL) {
                    494:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
                    495:     if (cc1 == NULL) {
                    496:       errorOxmisc2("KoxReq(): no more memory.");
                    497:       return(rob);
                    498:     }
                    499:     oxInitClient(cc1);
                    500:   }
                    501:
                    502:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                    503:   if (cc1 == NULL) {
                    504:     errorOxmisc2("KoxReq(): the first argument must be a client object.");
                    505:     return(rob);
                    506:   }
                    507:   if (func.tag != Sinteger) {
                    508:     errorOxmisc2("KoxReq(): the second argument must be an integer.");
                    509:     return(rob);
                    510:   }
                    511:   ans = oxReq(cc1,KopInteger(func),ob1);
                    512:   /* synchronize cc1 and client. */
                    513:   oxClientToObject(cc1,client);
                    514:
                    515:   return(KpoInteger(ans));
                    516: }
                    517:
                    518: struct object KoxGet(struct object client)
                    519: {
                    520:   int ans,k;
                    521:   static oxclientp cc1 = NULL;
1.25      takayama  522:   struct object rob = OINIT;
1.1       maekawa   523:   rob.tag = Snull;
                    524:   if (cc1 == NULL) {
                    525:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
                    526:     if (cc1 == NULL) {
                    527:       errorOxmisc2("KoxGet(): no more memory.");
                    528:       return(rob);
                    529:     }
                    530:     oxInitClient(cc1);
                    531:   }
                    532:
                    533:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                    534:   if (cc1 == NULL) {
                    535:     errorOxmisc2("KoxGet(): the first argument must be a client object.");
                    536:     return(rob);
                    537:   }
                    538:
                    539:   ans = oxGet(cc1,&rob,&k);
                    540:   /* synchronize cc1 and client. */
                    541:   oxClientToObject(cc1,client);
                    542:
                    543:   if (k) return(rob);
                    544:   else {
                    545:     return(KpoInteger(ans));
                    546:   }
                    547: }
                    548:
                    549: struct object KoxGetFromControl(struct object client)
                    550: {
                    551:   int ans;
                    552:   static oxclientp cc1 = NULL;
1.25      takayama  553:   struct object rob = OINIT;
1.1       maekawa   554:   rob.tag = Snull;
                    555:   if (cc1 == NULL) {
                    556:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
                    557:     if (cc1 == NULL) {
                    558:       errorOxmisc2("KoxGetFromControl(): no more memory.");
                    559:       return(rob);
                    560:     }
                    561:     oxInitClient(cc1);
                    562:   }
                    563:
                    564:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                    565:   if (cc1 == NULL) {
                    566:     errorOxmisc2("KoxGetFromControl(): the first argument must be a client object.");
                    567:     return(rob);
                    568:   }
                    569:
                    570:   ans = oxGetFromControl(cc1);
                    571:   /* synchronize cc1 and client. */
                    572:   oxClientToObject(cc1,client);
                    573:
                    574:   return(KpoInteger(ans));
                    575: }
                    576:
                    577: struct object KoxMultiSelect(struct object oclients,struct object t)
                    578: {
                    579:   static int first = 1;
                    580:   static int csize = 0;
                    581:   static oxclientp *clients = NULL;
                    582:   oxclientp cc1;
1.25      takayama  583:   struct object rob = OINIT;
1.1       maekawa   584:   int i;
                    585:   int tt;
1.25      takayama  586:   struct object ob1 = OINIT;
                    587:   struct object ob2 = OINIT;
                    588:   struct object ob0 = OINIT;
1.1       maekawa   589:   int size;
                    590:   int ans;
                    591:   int dataready[1024];
                    592:   int controlready[1024];
                    593:
                    594:   rob.tag = Snull;
                    595:   if (oclients.tag != Sarray) {
                    596:     errorOxmisc2("KoxMultiSelect(): the first argument must be an array.");
                    597:     return(rob);
                    598:   }
                    599:   size = getoaSize(oclients);
                    600:   if (first) {
                    601:     first = 0; csize = size;
                    602:     clients = (oxclientp *)mymalloc(sizeof(oxclientp)*(size+1));
1.12      takayama  603:     if (clients == NULL) {
1.1       maekawa   604:       errorOxmisc2("KoxMultiSelect(): no more memory.");
                    605:       return(rob);
                    606:     }
                    607:     for (i=0; i<size; i++) {
                    608:       clients[i] =  (oxclientp) mymalloc(sizeof(oxclient));
                    609:       if (clients[i] == NULL) {
1.12      takayama  610:         errorOxmisc2("KoxMultiSelect(): no more memory.");
                    611:         return(rob);
1.1       maekawa   612:       }
                    613:       oxInitClient(clients[i]);
                    614:     }
                    615:   }
                    616:   if (csize < size)  {
                    617:     first = 1;
                    618:     return(KoxMultiSelect(oclients,t));
                    619:   }
                    620:   for (i=0; i<size; i++) {
                    621:     ob0 = getoa(oclients,i);
                    622:     if (oxObjectToClient(ob0,clients[i]) == -1) return(rob);
                    623:   }
                    624:   if (t.tag != Sinteger) {
                    625:     errorOxmisc2("KoxMultiSelect(): the second argument must be an integer.");
                    626:   }
                    627:   tt = KopInteger(t);
                    628:   ans = oxclientMultiSelect(clients,dataready,controlready,size,tt);
                    629:   /* synchronize oclients and clients. */
                    630:   for (i=0; i<size; i++) {
                    631:     ob0 = getoa(oclients,i);
                    632:     oxClientToObject(clients[i],ob0);
                    633:     putoa(oclients,i,ob0);
                    634:   }
                    635:   rob = newObjectArray(3);
                    636:   putoa(rob,0,KpoInteger(ans));
                    637:   ob1 = newObjectArray(size);
                    638:   ob2 = newObjectArray(size);
                    639:   for (i=0; i<size; i++) {
                    640:     putoa(ob1,i,KpoInteger(dataready[i]));
                    641:     putoa(ob2,i,KpoInteger(controlready[i]));
                    642:   }
                    643:   putoa(rob,1,ob1);
                    644:   putoa(rob,2,ob2);
                    645:   return(rob);
                    646: }
                    647:
                    648: struct object KoxWatch(struct object client,struct object f)
1.12      takayama  649:      /* f is not used for now. It should be log file. */
1.1       maekawa   650: {
                    651:   int ans,k;
                    652:   static oxclientp cc1 = NULL;
1.25      takayama  653:   struct object rob = OINIT;
1.3       takayama  654:   extern int WatchStream;
1.1       maekawa   655:   rob.tag = Snull;
1.3       takayama  656:   if (client.tag == Sinteger) {
1.12      takayama  657:     if (KopInteger(client)) {
                    658:       WatchStream = 1;
                    659:     }else{
                    660:       WatchStream = 0;
                    661:     }
1.27      takayama  662:     return rob;
1.3       takayama  663:   }
1.1       maekawa   664:   if (cc1 == NULL) {
                    665:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
                    666:     if (cc1 == NULL) {
                    667:       errorOxmisc2("KoxWatch(): no more memory.");
                    668:       return(rob);
                    669:     }
                    670:     oxInitClient(cc1);
                    671:   }
                    672:
                    673:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                    674:   if (cc1 == NULL) {
                    675:     errorOxmisc2("KoxWatch(): the first argument must be a client object.");
                    676:     return(rob);
                    677:   }
                    678:
                    679:   k = fp2watch(cc1->datafp2,stdout);
                    680:   /* synchronize cc1 and client. */
                    681:   oxClientToObject(cc1,client);
                    682:
                    683:   return(KpoInteger(ans));
                    684: }
                    685:
1.18      takayama  686: struct object KoxLog(struct object client,struct object in,struct object out)
                    687: {
                    688:   int ans,k;
                    689:   static oxclientp cc1 = NULL;
1.25      takayama  690:   struct object rob = OINIT;
1.18      takayama  691:   rob.tag = Snull;
                    692:   if (cc1 == NULL) {
                    693:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
                    694:     if (cc1 == NULL) {
                    695:       errorOxmisc2("KoxLog(): no more memory.");
                    696:       return(rob);
                    697:     }
                    698:     oxInitClient(cc1);
                    699:   }
                    700:
                    701:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                    702:   if (cc1 == NULL) {
                    703:     errorOxmisc2("KoxLog(): the first argument must be a client object.");
                    704:     return(rob);
                    705:   }
                    706:
                    707:   if (in.tag != Sfile) {
                    708:        errorOxmisc2("KoxLog(): the second argument is not a file object.");
                    709:        return rob;
                    710:   }
                    711:   if (out.tag != Sfile) {
                    712:        errorOxmisc2("KoxLog(): the third argument is not a file object.");
                    713:        return rob;
                    714:   }
                    715:   k = fp2log(cc1->datafp2,in.rc.file,out.rc.file);
1.19      takayama  716:   fputc(cc1->engineByteOrder,out.rc.file); /* Output engineByteOrder. */
1.18      takayama  717:   /* synchronize cc1 and client. */
                    718:   oxClientToObject(cc1,client);
                    719:
                    720:   return(KpoInteger(ans));
                    721: }
                    722:
                    723: struct object KoxLogStop(struct object client) {
                    724:   static oxclientp cc1 = NULL;
1.25      takayama  725:   struct object rob = OINIT;
1.18      takayama  726:   rob.tag = Snull;
                    727:   if (cc1 == NULL) {
                    728:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
                    729:     if (cc1 == NULL) {
                    730:       errorOxmisc2("KoxLog(): no more memory.");
                    731:       return(rob);
                    732:     }
                    733:     oxInitClient(cc1);
                    734:   }
                    735:
                    736:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                    737:   if (cc1 == NULL) {
                    738:     errorOxmisc2("KoxLog(): the first argument must be a client object.");
                    739:     return(rob);
                    740:   }
                    741:   return(KpoInteger(fp2stopLog(cc1->datafp2)));
                    742: }
1.1       maekawa   743:
                    744: struct object KoxCloseClient(struct object client) {
                    745:   oxclientp cc1 = NULL;
                    746:   oxclient cc;
1.25      takayama  747:   struct object rob = OINIT;
1.1       maekawa   748:   rob.tag = Snull;
                    749:   cc1  = &cc;
                    750:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                    751:   if (cc1 == NULL) {
                    752:     errorOxmisc2("KoxCloseClient(): the first argument must be a client object.");
                    753:     return(rob);
                    754:   }
                    755:
                    756:   fp2fflush(cc1->datafp2);
                    757:   if (cc1->humanio) {
                    758:     /* Do not close the file. */
                    759:     return(KpoInteger(0));
                    760:   }
                    761:   switch (cc1->type) {
                    762:   case CLIENT_SOCKET:
                    763:     fp2fclose(cc1->datafp2);
1.28    ! takayama  764:     {int r; r=close(cc1->controlfd);}
1.1       maekawa   765:     break;
                    766:   case CLIENT_FILE:
                    767:     fp2fclose(cc1->datafp2);
1.28    ! takayama  768:     {int r; r=close(cc1->controlfd);}
1.1       maekawa   769:     break;
                    770:   default:
                    771:     errorOxmisc2("Unknown client->type\n");
                    772:     break;
                    773:   }
1.14      takayama  774:   oxClientListRemove(client);
1.1       maekawa   775:   return(KpoInteger(0));
                    776:
                    777: }
                    778:
                    779: static int cmoCheck00(struct object obj,int cmo[], int n) {
                    780:   int i,j,m;
                    781:   int ttt;
                    782: #define CHECK00_N  4098      /* look up stackm.h and kclass.h */
                    783:   static int typeTrans[CHECK00_N];
                    784:   static int init = 0;
1.5       takayama  785:   /* if n == 0, report the cmo tag of the object obj.
1.12      takayama  786:      If it cannot be translated to cmo, then return -1. */
1.5       takayama  787:
1.1       maekawa   788:   if (!init) {
                    789:     for (i=0; i<CHECK00_N; i++) {
                    790:       typeTrans[i] = 0;  /* unknown cmo number */
                    791:     }
                    792:     typeTrans[Snull] = CMO_NULL;
                    793:     typeTrans[Sinteger] = CMO_INT32;
                    794:     typeTrans[Sdollar] = CMO_STRING;
                    795:     if (OxVersion >= 199907170) {
                    796:       typeTrans[SuniversalNumber] = CMO_ZZ;
                    797:     }else{
                    798:       typeTrans[SuniversalNumber] = CMO_ZZ_OLD;
                    799:     }
                    800:     typeTrans[Sarray] = CMO_LIST;
                    801:     /* typeTrans[Spoly] = CMO_DMS;  */
                    802:     typeTrans[Spoly] = CMO_DISTRIBUTED_POLYNOMIAL;
                    803:     typeTrans[Sdouble] = CMO_64BIT_MACHINE_DOUBLE;
1.20      takayama  804:        typeTrans[SrationalFunction] = CMO_RATIONAL;
1.1       maekawa   805:     typeTrans[CLASSNAME_ERROR_PACKET]   = CMO_ERROR2;
                    806:     typeTrans[CLASSNAME_mathcap] = CMO_MATHCAP;
                    807:     typeTrans[CLASSNAME_indeterminate] = CMO_INDETERMINATE;
                    808:     typeTrans[CLASSNAME_tree] = CMO_TREE;
                    809:     typeTrans[CLASSNAME_recursivePolynomial] = CMO_RECURSIVE_POLYNOMIAL;
                    810:     typeTrans[CLASSNAME_polynomialInOneVariable] = CMO_POLYNOMIAL_IN_ONE_VARIABLE;
                    811:     init = 1;
                    812:   }
                    813:   ttt = typeTrans[obj.tag];
                    814:   if (obj.tag == Sclass) {
                    815:     ttt = typeTrans[ectag(obj)];
                    816:   }
1.5       takayama  817:   /* Only report the cmo tag. */
                    818:   if (n == 0) {
1.12      takayama  819:     if (ttt == 0) return(-1);
                    820:     else return(ttt);
1.5       takayama  821:   }
1.1       maekawa   822:
                    823:   for (i=0; i<n; i++) {
                    824:     if (ttt == cmo[i]) {
                    825:       if (ttt != CMO_LIST) return(1);
                    826:       else {
1.12      takayama  827:         m = getoaSize(obj);
                    828:         for (j=0; j<m; j++) {
                    829:           if (!cmoCheck00(getoa(obj,j),cmo,n)) return(0);
                    830:         }
                    831:         return(1);
1.1       maekawa   832:       }
                    833:     }
                    834:   }
                    835:   if (DebugMathCap) {
                    836:     if (DebugMathCap && 1) {
                    837:       fprintf(stderr,"Type translation table (internal object tag --> CMO tag)\n");
                    838:       for (i=0; i<20; i++) {
1.12      takayama  839:         printf("%d ", typeTrans[i]);
1.1       maekawa   840:       }
                    841:       printf("\n");
                    842:     }
                    843:     fprintf(stderr,"The type of the argument object in sm1 is %d.\n",obj.tag);
                    844:     fprintf(stderr,"The type of the argument object in CMO is %d.\n",ttt);
                    845:     fprintf(stderr,"Available CMO tags in mathcap= %d elements : [ ",n);
                    846:     for (i=0; i<n; i++) {
                    847:       fprintf(stderr," %d ",cmo[i]);
                    848:     }
                    849:     fprintf(stderr," ] \n");
                    850:   }
                    851:   return(0);
                    852: }
                    853:
                    854: int cmoCheckMathCap(struct object obj, struct object *obp)
                    855: {
1.25      takayama  856:   struct object mathcap = OINIT;
                    857:   struct object cmolist = OINIT;
                    858:   struct object mathcapMain = OINIT;
                    859:   struct object mathcapThird = OINIT;
                    860:   struct object ox = OINIT;
                    861:   struct object oxtag = OINIT;
                    862:   struct object ob0 = OINIT;
1.4       takayama  863:   int oxsize;
1.1       maekawa   864:   int n;
                    865:   int i;
                    866: #define CMO_CHECK_MATH_CAP_LIST_SIZE 1024
                    867:   int cmo[CMO_CHECK_MATH_CAP_LIST_SIZE];
                    868:   if (obp == NULL) return(1);
1.2       takayama  869:   /* printObject(*obp,0,stderr); for debug*/
1.1       maekawa   870:   if (obp->tag != Sarray) {
                    871:     fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    872:     printObject(*obp,0,stderr);
                    873:     fprintf(stderr,"\n");
                    874:     errorOxmisc2("cmoCheckMathCap: format error in the client->mathcapObjp field.\n");
                    875:   }
                    876:   mathcap = *obp;
1.2       takayama  877:   /* Example of mathcap
1.12      takayama  878:      [    $mathcap-object$ ,
                    879:      [    [    199909080 , $Ox_system=ox_sm1.plain$ , $Version=2.991106$ ,
                    880:      $HOSTTYPE=i386$ ]  ,
                    881:      [    262 , 263 , 264 , 265 , 266 , 268 , 269 , 272 , 273 , 275 ,
                    882:      276 ]  ,
                    883:      [    [    514  , [    2130706434 , 1 , 2 , 4 , 5 , 17 , 19 , 20 , 22 , 23 , 24 , 25 , 26 , 30 , 31 , 60 , 61 , 27 , 33 , 40 , 16 , 34 ] ] ]  ]  ]
1.2       takayama  884:   */
                    885:
1.1       maekawa   886:   n = getoaSize(mathcap);
                    887:   if (n < 2) {
                    888:     fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    889:     printObject(*obp,0,stderr);
                    890:     fprintf(stderr,"\n");
                    891:     errorOxmisc2("cmoCheckMathCap: length of mathcap is wrong in the client->mathcapObjp field.\n");
                    892:   }
1.2       takayama  893:   ob0 = getoa(mathcap,0);
                    894:   if (ob0.tag != Sdollar) {
                    895:     fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    896:     printObject(*obp,0,stderr);
                    897:     fprintf(stderr,"\n");
                    898:     errorOxmisc2("cmoCheckMathCap: The first field must be the string mathcap-object.\n");
                    899:   }
                    900:   if (strcmp(KopString(ob0),"mathcap-object") != 0) {
                    901:     fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    902:     printObject(*obp,0,stderr);
                    903:     fprintf(stderr,"\n");
                    904:     errorOxmisc2("cmoCheckMathCap: The mathcap must be of the form [(mathcap-object) [...]]\n");
                    905:   }
                    906:
1.1       maekawa   907:   /* I should check
1.12      takayama  908:      getoa(getoa(mathcap,1),2)
1.1       maekawa   909:      contains OX_DATA.
                    910:      It has not yet implemented.
                    911:   */
1.2       takayama  912:   mathcapMain = getoa(mathcap,1);
                    913:   if (mathcapMain.tag != Sarray) {
                    914:     fprintf(stderr,"cmoCheckMathCap: mathcap[1] is \n");
                    915:     printObject(mathcapMain,0,stderr);
                    916:     fprintf(stderr,"\n");
                    917:     errorOxmisc2("cmoCheckMathCap: format error in the (client->mathcapObjp)[1] field. It should be an array.\n");
                    918:   }
                    919:   if (getoaSize(mathcapMain) < 3) {
                    920:     fprintf(stderr,"cmoCheckMathCap: mathcap[1] is \n");
                    921:     printObject(mathcapMain,0,stderr);
                    922:     fprintf(stderr,"\n");
                    923:     errorOxmisc2("cmoCheckMathCap: format error in the (client->mathcapObjp)[1] field. It should be an array of which length is more than 2.\n");
                    924:   }
1.4       takayama  925:   mathcapThird = getoa(mathcapMain,2);
                    926:   oxsize = getoaSize(mathcapThird);
                    927:   for (i=0; i<oxsize; i++) {
                    928:     ox = getoa(mathcapThird,i);
                    929:     if (ox.tag != Sarray) {
                    930:       fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    931:       printObject(*obp,0,stderr);
                    932:       fprintf(stderr,"\n");
                    933:       errorOxmisc2("cmoCheckMathCap: the third element of mathcap is a list of lists.");
                    934:     }
                    935:     if (getoaSize(ox) != 0) {
                    936:       oxtag = getoa(ox,0);
                    937:       if (oxtag.tag != Sinteger) {
1.12      takayama  938:         fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    939:         printObject(*obp,0,stderr);
                    940:         fprintf(stderr,"\n");
                    941:         errorOxmisc2("cmoCheckMathCap: the third element of mathcap must be [OX_DATA_xxx, [  ]].");
1.4       takayama  942:       }
                    943:       if (KopInteger(oxtag) == OX_DATA) {
1.12      takayama  944:         if (getoaSize(ox) > 1) {
                    945:           cmolist = getoa(ox,1);
                    946:           if (cmolist.tag != Sarray) {
                    947:             fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    948:             printObject(*obp,0,stderr);
                    949:             fprintf(stderr,"\n");
                    950:             errorOxmisc2("cmoCheckMathCap: mathcap[1] must be an array of integers.\n");
                    951:           }
                    952:           n = getoaSize(cmolist);
                    953:           if (n > CMO_CHECK_MATH_CAP_LIST_SIZE) {
                    954:             errorOxmisc2("cmoCheckMathCap: Too big cmo list.\n");
                    955:           }
                    956:           for (i=0; i<n; i++) {
                    957:             cmo[i] = KopInteger(getoa(cmolist,i));
                    958:           }
                    959:         }else{
                    960:           fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    961:           printObject(*obp,0,stderr);
                    962:           fprintf(stderr,"\nox=");
                    963:           printObject(ox,0,stderr);
                    964:           errorOxmisc2("cmoCheckMathCap: [OX_DATA, cmolist]");
                    965:         }
1.4       takayama  966:       }
                    967:     }
1.1       maekawa   968:   }
                    969:   return(cmoCheck00(obj,cmo,n));
                    970: }
                    971:
1.12      takayama  972:
1.1       maekawa   973: struct object KoxGenPortFile(void) {
1.25      takayama  974:   struct object ob = OINIT;
1.1       maekawa   975:   ob = KpoString(oxGenPortFile());
                    976:   return(ob);
                    977: }
                    978: void KoxRemovePortFile(void) {
                    979:   oxRemovePortFile();
                    980: }
                    981:
                    982: void oxPushMathCap(struct mathCap *mathcap)
                    983: {
1.25      takayama  984:   struct object rob = OINIT;
1.1       maekawa   985:   rob = newMathCap(mathcap);
                    986:   Kpush(rob);
                    987: }
                    988:
                    989: struct object KoxGenPass(void) {
1.25      takayama  990:   struct object rob = OINIT;
1.1       maekawa   991:   rob = KpoString(oxGenPass());
                    992:   return(rob);
                    993: }
                    994:
                    995: struct object KoxGetPort(struct object host)
                    996: {
1.25      takayama  997:   struct object rob = OINIT;
1.1       maekawa   998:   int fdStream, fdControl;
                    999:   int portStream, portControl;
                   1000:   extern int OpenedSocket;
                   1001:   char *sname;
                   1002:   rob = NullObject;
                   1003:   if (host.tag != Sdollar) {
                   1004:     errorOxmisc2("KoxGetPort: argument is not a string.");
                   1005:     return(rob);
                   1006:   }
                   1007:   sname = KopString(host);
                   1008:   fdControl = socketOpen(sname,0);
                   1009:   portControl = OpenedSocket;
                   1010:   fdStream = socketOpen(sname,0);
                   1011:   portStream = OpenedSocket;
                   1012:   rob = newObjectArray(4);
                   1013:   putoa(rob,0,KpoInteger(fdStream));
                   1014:   putoa(rob,1,KpoInteger(portStream));
                   1015:   putoa(rob,2,KpoInteger(fdControl));
                   1016:   putoa(rob,3,KpoInteger(portControl));
1.10      takayama 1017:   return(rob);
                   1018: }
                   1019: struct object KoxGetPort1(struct object host)
                   1020: {
1.25      takayama 1021:   struct object rob = OINIT;
1.10      takayama 1022:   int fdStream;
                   1023:   int portStream;
                   1024:   extern int OpenedSocket;
                   1025:   char *sname;
                   1026:   rob = NullObject;
                   1027:   if (host.tag != Sdollar) {
                   1028:     errorOxmisc2("KoxGetPort1: argument is not a string.");
                   1029:     return(rob);
                   1030:   }
                   1031:   sname = KopString(host);
                   1032:   fdStream = socketOpen(sname,0);
                   1033:   portStream = OpenedSocket;
                   1034:   rob = newObjectArray(2);
                   1035:   putoa(rob,0,KpoInteger(fdStream));
                   1036:   putoa(rob,1,KpoInteger(portStream));
1.1       maekawa  1037:   return(rob);
                   1038: }
                   1039:
                   1040: struct object KoxCreateClient2(struct object peer,
1.12      takayama 1041:                                struct object ipmask,
                   1042:                                struct object pass)
1.1       maekawa  1043: {
1.25      takayama 1044:   struct object rob = OINIT;
1.1       maekawa  1045:   oxclientp client;
                   1046:   int fdStream, portStream, fdControl, portControl;
                   1047:   int i;
1.25      takayama 1048:   struct object ob1 = OINIT;
                   1049:   struct object opassControl = OINIT;
                   1050:   struct object opassData = OINIT;
1.1       maekawa  1051:   rob.tag = Snull;
                   1052:   if (peer.tag != Sarray) {
                   1053:     errorOxmisc2("KoxCreateClient2(): The first argument must be an array [fdStream, portStream, fdControl, portControl]");
                   1054:     return(rob);
                   1055:   }
                   1056:   if (getoaSize(peer) != 4) {
                   1057:     errorOxmisc2("KoxCreateClient2(): The first argument must be an array [fdStream, portStream, fdControl, portControl] of size 4.");
                   1058:     return(rob);
                   1059:   }
                   1060:   for (i=0; i<4; i++) {
                   1061:     ob1 = getoa(peer,i);
                   1062:     if (ob1.tag != Sinteger) {
                   1063:       errorOxmisc2("KoxCreateClient2(): The element of the first argument must be an integer.");
                   1064:     }
                   1065:   }
                   1066:   fdStream = KopInteger(getoa(peer,0));
                   1067:   portStream = KopInteger(getoa(peer,1));
                   1068:   fdControl = KopInteger(getoa(peer,2));
                   1069:   portControl = KopInteger(getoa(peer,3));
                   1070:
                   1071:   if (ipmask.tag != Sinteger) {
                   1072:     errorOxmisc2("KoxCreateClient2(): ipmask must be an integer.");
                   1073:   }
1.23      takayama 1074:   if (pass.tag == Sdollar) {
                   1075:     opassControl = pass; opassData = pass;
                   1076:   }else if (pass.tag == Sarray) {
                   1077:     if (getoaSize(pass) < 2) errorOxmisc2("KoxCreateClient2: #passArray < 2.");
                   1078:     opassControl = getoa(pass,0);
                   1079:     opassData = getoa(pass,1);
                   1080:   }else{
                   1081:     errorOxmisc2("KoxCreateClient2(): pass must be a string or an array.");
                   1082:   }
                   1083:   if ((opassControl.tag != Sdollar) || (opassData.tag != Sdollar)) {
                   1084:     errorOxmisc2("KoxCreateClient2(): opassControl or opassData must be a string.");
1.1       maekawa  1085:   }
                   1086:
                   1087:   client = oxCreateClient2(fdStream, portStream, fdControl, portControl,
1.23      takayama 1088:                            KopInteger(ipmask),
                   1089:                            KopString(opassControl),KopString(opassData));
1.1       maekawa  1090:   if (client == NULL) {
                   1091:     errorOxmisc2("KoxCreateClient2(): Open error.");
                   1092:     return(rob);
                   1093:   }
                   1094:   rob = newObjectArray(N_OF_CLIENT_FIELDS);
                   1095:   oxClientToObject(client,rob);
1.14      takayama 1096:   oxClientListUpdate(rob);
1.1       maekawa  1097:   return(rob);
1.5       takayama 1098: }
                   1099:
                   1100: int KgetCmoTagOfObject(struct object obj) {
                   1101:   int k;
                   1102:   k=cmoCheck00(obj,(int *)NULL,0);
                   1103:   return(k);
1.1       maekawa  1104: }
                   1105:
1.28    ! takayama 1106: int errorOxmisc2(char *s) {
1.6       takayama 1107:   SET_MYERROROUT;
1.1       maekawa  1108:   fprintf(MyErrorOut,"error in oxmisc2.c: %s\n",s);
                   1109:   errorKan1("%s\n","  ");
1.28    ! takayama 1110:   return 0;
1.7       takayama 1111: }
                   1112:
                   1113: struct object KoxPushCMD(struct object client,struct object cmd) {
                   1114:   int ans;
                   1115:   static oxclientp cc1 = NULL;
1.25      takayama 1116:   struct object rob = OINIT;
1.7       takayama 1117:   rob.tag = Snull;
                   1118:   if (cc1 == NULL) {
                   1119:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
                   1120:     if (cc1 == NULL) {
                   1121:       errorOxmisc2("KoxReq(): no more memory.");
                   1122:       return(rob);
                   1123:     }
                   1124:     oxInitClient(cc1);  /* BUG: is it fine? */
                   1125:   }
                   1126:
                   1127:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                   1128:   if (cc1 == NULL) {
                   1129:     errorOxmisc2("KoxReq(): the first argument must be a client object.");
                   1130:     return(rob);
                   1131:   }
                   1132:   if (cmd.tag != Sinteger) {
                   1133:     errorOxmisc2("KoxReq(): the second argument must be an integer.");
                   1134:     return(rob);
                   1135:   }
                   1136:   /* BUG: check the mathcap */
                   1137:   oxSendOXheader(cc1->datafp2,OX_COMMAND,SerialOX++);
                   1138:   oxSendInt32(cc1->datafp2,KopInteger(cmd));
                   1139:   /* synchronize cc1 and client. */
                   1140:   oxClientToObject(cc1,client);
                   1141:   return(cmd);
                   1142: }
                   1143:
                   1144: struct object KoxPushCMO(struct object client,struct object ob) {
                   1145:   int ans;
                   1146:   static oxclientp cc1 = NULL;
1.25      takayama 1147:   struct object rob = OINIT;
1.7       takayama 1148:   rob.tag = Snull;
                   1149:   if (cc1 == NULL) {
                   1150:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
                   1151:     if (cc1 == NULL) {
                   1152:       errorOxmisc2("KoxReq(): no more memory.");
                   1153:       return(rob);
                   1154:     }
                   1155:     oxInitClient(cc1);  /* BUG: is it fine? */
                   1156:   }
                   1157:
                   1158:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                   1159:   if (cc1 == NULL) {
                   1160:     errorOxmisc2("KoxReq(): the first argument must be a client object.");
                   1161:     return(rob);
                   1162:   }
                   1163:
                   1164:   /* request to the data channel */
                   1165:   if (cc1->dstate != DSTATE_ANY) {
                   1166:     errorOxmisc2("oxPushCMO: cc1->dstate != DSTATE_ANY, data channel is not ready to send data.\n");
                   1167:     return(rob);
                   1168:   }
                   1169:
                   1170:   if (!cmoCheckMathCap(ob,(struct object *)cc1->mathcapObjp)) {
1.12      takayama 1171:     errorOxmisc2("oxPushCMO: your peer does not understand this cmo.\n");
                   1172:     return(rob);
1.7       takayama 1173:   }
                   1174:   oxSendOXheader(cc1->datafp2,OX_DATA,SerialOX++);
                   1175:   cmoObjectToStream2(ob,cc1->datafp2);
                   1176:   /* synchronize cc1 and client. */
                   1177:   oxClientToObject(cc1,client);
                   1178:   return(ob);
1.8       takayama 1179: }
                   1180:
                   1181: oxclientp oxCreateControl_RFC_101(int fdstream,int portStream,
1.12      takayama 1182:                                   int ipmask,char *pass);
1.8       takayama 1183: struct object KoxCreateControl_RFC_101(struct object peer,struct object ipmask,struct object pass)
                   1184: {
1.25      takayama 1185:   struct object rob = OINIT;
1.8       takayama 1186:   oxclientp client;
                   1187:   int fdStream, portStream;
                   1188:   int i;
1.25      takayama 1189:   struct object ob1 = OINIT;
1.8       takayama 1190:   rob.tag = Snull;
                   1191:   if (peer.tag != Sarray) {
                   1192:     errorOxmisc2("KoxCreateControl_RFC_101(): The first argument must be an array [fdStream, portStream]");
                   1193:     return(rob);
                   1194:   }
                   1195:   if (getoaSize(peer) != 2 ) {
                   1196:     errorOxmisc2("KoxCreateControl_RFC_101(): The first argument must be an array [fdStream, portStream] of size 2.");
                   1197:     return(rob);
                   1198:   }
                   1199:   for (i=0; i<getoaSize(peer); i++) {
                   1200:     ob1 = getoa(peer,i);
                   1201:     if (ob1.tag != Sinteger) {
                   1202:       errorOxmisc2("KoxCreateControl_RFC_101(): The element of the first argument must be an integer.");
                   1203:     }
                   1204:   }
                   1205:   fdStream = KopInteger(getoa(peer,0));
                   1206:   portStream = KopInteger(getoa(peer,1));
                   1207:
                   1208:   if (ipmask.tag != Sinteger) {
                   1209:     errorOxmisc2("KoxCreateControl_RFC_101(): ipmask must be an integer.");
                   1210:   }
                   1211:   if (pass.tag != Sdollar) {
                   1212:     errorOxmisc2("KoxCreateControl_RFC_101(): pass must be a string.");
                   1213:   }
                   1214:
                   1215:   client = oxCreateControl_RFC_101(fdStream, portStream,
1.12      takayama 1216:                                    KopInteger(ipmask), KopString(pass));
1.8       takayama 1217:   if (client == NULL) {
                   1218:     errorOxmisc2("KoxCreateControl_RFC_101(): Open error.");
                   1219:     return(rob);
                   1220:   }
                   1221:   rob = newObjectArray(N_OF_CLIENT_FIELDS);
                   1222:   oxClientToObject(client,rob);
                   1223:   return(rob);
                   1224: }
                   1225:
                   1226: oxclientp oxCreateControl_RFC_101(int fdstream,int portStream,
1.12      takayama 1227:                                   int ipmask,char *pass)
1.8       takayama 1228: {
                   1229:   int v = 0;
                   1230:   int fdControl = -1;
                   1231:   int fdStream = -1;
                   1232:   int m;
                   1233:
                   1234:   char *s;
                   1235:   oxclientp client;
1.13      takayama 1236: #if defined(__CYGWIN__)
                   1237:   extern sigjmp_buf MyEnv_oxmisc;
                   1238: #else
                   1239:   extern jmp_buf MyEnv_oxmisc;
                   1240: #endif
1.8       takayama 1241:   int engineByteOrder;
                   1242:   extern int Quiet;
                   1243:
                   1244:   v = !Quiet;
                   1245:
                   1246:   switch(ipmask) {
                   1247:   case 0:/* only local */
                   1248:     fdStream  = socketAcceptLocal(fdstream);
                   1249:     break;
                   1250:   default:/* any */
                   1251:     fdStream  = socketAccept(fdstream);
                   1252:     break;
                   1253:   }
                   1254:   if (v) fprintf(stderr,"\nControl port %d : Connected.\n",portStream);
                   1255:
                   1256:   if (fdStream == -1 ) {
                   1257:     fprintf(stderr,"\nOpen error in oxCreateControl_RFC_101.\n");
                   1258:     return(NULL);
                   1259:   }
                   1260:
                   1261:   /* Authentication by password. */
                   1262:   m = strlen(pass);
                   1263:   s = (char *)mymalloc(sizeof(char)*(m+1));
1.28    ! takayama 1264:   {int r; r=read(fdStream,s,m+1);} s[m] = '\0';
1.8       takayama 1265:   if (strcmp(s,pass) != 0) {
                   1266:     fprintf(stderr,"oxCreateControl_RFC_101(): password authentication failed for control channel.\n");
1.28    ! takayama 1267:     {int r; r=close(fdStream);}
1.8       takayama 1268:     return(NULL);
                   1269:   }
                   1270:
                   1271:
                   1272:   engineByteOrder = oxSetByteOrder(fdStream);
                   1273:   if (v) fprintf(stderr,"Byte order for control stackmacine is %s.\n",
1.12      takayama 1274:                  (engineByteOrder == 0? "network byte order":
                   1275:                   (engineByteOrder == 1? "little indican":
                   1276:                    "big indian")));
1.8       takayama 1277:
                   1278:
                   1279:   client = (oxclientp) mymalloc(sizeof(oxclient));
                   1280:   oxInitClient(client);
                   1281:   client->datafp2 = fp2open(fdStream);
                   1282:   if (client->datafp2 == NULL) {
                   1283:     fprintf(stderr,"oxCreateControl_RFC_101(): fp2open(fd) failed.\n");
                   1284:     return(NULL);
                   1285:   }
                   1286:   client->dataport = portStream;
                   1287:   client->controlport = -1;
                   1288:   client->controlfd = -1;
1.14      takayama 1289:   client->id = oxGetClientID();
1.11      takayama 1290:   client->type = CLIENT_SOCKET; /* socket */
                   1291:   client->engineByteOrder = engineByteOrder;
                   1292:   client->controlByteOrder = -1;
                   1293:   return(client);
                   1294: }
                   1295:
                   1296: oxclientp oxCreateEngine_RFC_101(int fdstream,int portStream,
1.12      takayama 1297:                                  int ipmask,char *pass, int engineID);
1.11      takayama 1298: struct object KoxCreateEngine_RFC_101(struct object peer,struct object ipmask,struct object pass, struct object engineID)
                   1299: {
1.25      takayama 1300:   struct object rob = OINIT;
1.11      takayama 1301:   oxclientp client;
                   1302:   int fdStream, portStream;
                   1303:   int i;
1.25      takayama 1304:   struct object ob1 = OINIT;
1.11      takayama 1305:   rob.tag = Snull;
                   1306:   if (peer.tag != Sarray) {
                   1307:     errorOxmisc2("KoxCreateEngine_RFC_101(): The first argument must be an array [fdStream, portStream]");
                   1308:     return(rob);
                   1309:   }
                   1310:   if (getoaSize(peer) != 2 ) {
                   1311:     errorOxmisc2("KoxCreateEngine_RFC_101(): The first argument must be an array [fdStream, portStream] of size 2.");
                   1312:     return(rob);
                   1313:   }
                   1314:   for (i=0; i<getoaSize(peer); i++) {
                   1315:     ob1 = getoa(peer,i);
                   1316:     if (ob1.tag != Sinteger) {
                   1317:       errorOxmisc2("KoxCreateEngine_RFC_101(): The element of the first argument must be an integer.");
                   1318:     }
                   1319:   }
                   1320:   fdStream = KopInteger(getoa(peer,0));
                   1321:   portStream = KopInteger(getoa(peer,1));
                   1322:
                   1323:   if (ipmask.tag != Sinteger) {
                   1324:     errorOxmisc2("KoxCreateEngine_RFC_101(): ipmask must be an integer.");
                   1325:   }
                   1326:   if (pass.tag != Sdollar) {
                   1327:     errorOxmisc2("KoxCreateEngine_RFC_101(): pass must be a string.");
                   1328:   }
                   1329:   if (engineID.tag != Sinteger) {
                   1330:     errorOxmisc2("KoxCreateEngine_RFC_101(): engineID must be an integer.");
                   1331:   }
                   1332:
                   1333:   client = oxCreateEngine_RFC_101(fdStream, portStream,
1.12      takayama 1334:                                   KopInteger(ipmask), KopString(pass),KopInteger(engineID));
1.11      takayama 1335:   if (client == NULL) {
                   1336:     errorOxmisc2("KoxCreateEngine_RFC_101(): Open error.");
                   1337:     return(rob);
                   1338:   }
                   1339:   rob = newObjectArray(N_OF_CLIENT_FIELDS);
                   1340:   oxClientToObject(client,rob);
1.14      takayama 1341:   oxClientListUpdate(rob);
1.11      takayama 1342:   return(rob);
                   1343: }
                   1344:
                   1345: oxclientp oxCreateEngine_RFC_101(int fdstream,int portStream,
1.12      takayama 1346:                                  int ipmask,char *pass,int engineID)
1.11      takayama 1347: {
                   1348:   int v = 0;
                   1349:   int fdControl = -1;
                   1350:   int fdStream = -1;
                   1351:   int m;
                   1352:
                   1353:   char *s;
                   1354:   oxclientp client;
1.13      takayama 1355: #if defined(__CYGWIN__)
                   1356:   extern sigjmp_buf MyEnv_oxmisc;
                   1357: #else
                   1358:   extern jmp_buf MyEnv_oxmisc;
                   1359: #endif
1.11      takayama 1360:   int engineByteOrder;
                   1361:   extern int Quiet;
                   1362:
                   1363:   v = !Quiet;
                   1364:
                   1365:   switch(ipmask) {
                   1366:   case 0:/* only local */
                   1367:     fdStream  = socketAcceptLocal(fdstream);
                   1368:     break;
                   1369:   default:/* any */
                   1370:     fdStream  = socketAccept(fdstream);
                   1371:     break;
                   1372:   }
                   1373:   if (v) fprintf(stderr,"\nEngine port %d : Connected.\n",portStream);
                   1374:
                   1375:   if (fdStream == -1 ) {
                   1376:     fprintf(stderr,"\nOpen error in oxCreateEngine_RFC_101.\n");
                   1377:     return(NULL);
                   1378:   }
                   1379:
                   1380:   /* Authentication by password. */
                   1381:   /*  skip password check for now. BUG.
1.12      takayama 1382:       m = strlen(pass);
                   1383:       s = (char *)mymalloc(sizeof(char)*(m+1));
                   1384:       read(fdStream,s,m+1); s[m] = '\0';
                   1385:       if (strcmp(s,pass) != 0) {
                   1386:       fprintf(stderr,"oxCreateEngine_RFC_101(): password authentication failed for control channel.\n");
                   1387:       close(fdStream);
                   1388:       return(NULL);
                   1389:       }
1.11      takayama 1390:   */
                   1391:
                   1392:   engineByteOrder = oxSetByteOrder(fdStream);
                   1393:   if (v) fprintf(stderr,"Byte order for engine stackmacine is %s.\n",
1.12      takayama 1394:                  (engineByteOrder == 0? "network byte order":
                   1395:                   (engineByteOrder == 1? "little indican":
                   1396:                    "big indian")));
1.11      takayama 1397:
                   1398:
                   1399:   client = (oxclientp) mymalloc(sizeof(oxclient));
                   1400:   oxInitClient(client);
                   1401:   client->datafp2 = fp2open(fdStream);
                   1402:   if (client->datafp2 == NULL) {
                   1403:     fprintf(stderr,"oxCreateEngine_RFC_101(): fp2open(fd) failed.\n");
                   1404:     return(NULL);
                   1405:   }
                   1406:   client->dataport = portStream;
                   1407:   client->controlport = -1;
                   1408:   client->controlfd = -1;
1.16      takayama 1409:   client->id = oxGetClientID();
                   1410:   client->engineID = engineID;
1.8       takayama 1411:   client->type = CLIENT_SOCKET; /* socket */
                   1412:   client->engineByteOrder = engineByteOrder;
                   1413:   client->controlByteOrder = -1;
                   1414:   return(client);
1.1       maekawa  1415: }
1.14      takayama 1416:
                   1417: void oxClientListUpdate(struct object ob) {
                   1418:   int id;
                   1419:   extern struct object OxClientList[];
                   1420:   id = KopInteger(getoa(ob,8));
                   1421:   /* printf("id=%d\n",id); */
                   1422:   if ((id <MAX_N_OF_CLIENT) && (id >= 0)) {
                   1423:        OxClientList[id] = ob;
                   1424:   }else{
                   1425:        errorOxmisc2("oxClientListUpdate(): the client table is full.\n");
                   1426:   }
                   1427: }
                   1428: void oxClientListRemove(struct object ob) {
                   1429:   int id;
                   1430:   extern struct object OxClientList[];
                   1431:   id = KopInteger(getoa(ob,8));
                   1432:   if ((id <MAX_N_OF_CLIENT) && (id >= 0)) {
                   1433:        (OxClientList[id]).tag = Snull;
                   1434:   }else{
                   1435:        /* errorOxmisc2("oxClientListRemove(): the client table is full.\n");*/
                   1436:   }
                   1437: }
1.17      takayama 1438: static void KoxCleanClientList() {
                   1439:   extern int OxClientListn;
                   1440:   extern struct object OxClientList[];
                   1441:   int i,j,n;
1.25      takayama 1442:   struct object ob = OINIT;
1.17      takayama 1443:   n = 0;
                   1444:   for (i=0; i<OxClientListn; i++) {
                   1445:        if ((OxClientList[i]).tag != Snull) {
                   1446:          if (!isItClientObject(OxClientList[i])) {
                   1447:                (OxClientList[i]).tag = Snull;
                   1448:          }
                   1449:        }
                   1450:   }
                   1451: }
1.14      takayama 1452: struct object KoxGetClientList() {
                   1453:   extern int OxClientListn;
                   1454:   extern struct object OxClientList[];
                   1455:   int i,j,n;
1.25      takayama 1456:   struct object rob = OINIT;
1.17      takayama 1457:   KoxCleanClientList();
1.14      takayama 1458:   n = 0;
                   1459:   for (i=0; i<OxClientListn; i++) {
                   1460:        if ((OxClientList[i]).tag != Snull) n++;
                   1461:   }
                   1462:   rob = newObjectArray(n);
                   1463:   for (i=0, j=0; i<OxClientListn; i++) {
                   1464:        if ((OxClientList[i]).tag != Snull) {
                   1465:          if (j >= n) {
                   1466:                j=0;
                   1467:                errorOxmisc2("oxGetClientList(): the client table is broken.\n");
                   1468:          }
                   1469:          putoa(rob,j,OxClientList[i]);
                   1470:          j++;
                   1471:        }
                   1472:   }
                   1473:   return rob;
                   1474: }
                   1475:
                   1476:

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