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

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

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