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

1.7     ! takayama    1: /* $OpenXM: OpenXM/src/kan96xx/plugin/oxmisc2.c,v 1.6 2000/03/20 01:53:47 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"
                      6: extern FILE *MyErrorOut;
1.6       takayama    7: #define SET_MYERROROUT { if (MyErrorOut == NULL) MyErrorOut=stdout; }
                      8: /* It is also defined in oxmisc.c */
                      9:
1.1       maekawa    10: extern int SerialOX; /* defined in SerialOX */
                     11:
                     12: extern int OxVersion;
                     13:
                     14: int DebugMathCap = 1;
                     15:
                     16:
                     17:
                     18: int oxGet(oxclientp client, struct object *op,int *isObj)
                     19: /* This method should be synchronized. */
                     20: /* oxGet is a function for client. */
                     21: {
                     22:   int ans;
                     23:   ox_stream os;
                     24:   int m;
                     25:   struct object rob;
                     26:   int sss;  /* Serial number of the recieved packet. */
                     27:   *isObj = 0;
                     28:   op->tag = Snull;
                     29:   os = client->datafp2;
                     30:   switch(client->dstate) {
                     31:   case DSTATE_ANY:
                     32:     m = oxGetOXheader(os,&sss);
                     33:     switch(m) {
                     34:     case OX_DATA:
                     35:       client->dstate = DSTATE_WAIT_OX_DATA;
                     36:       return(oxGet(client,op,isObj));
                     37:     case OX_SYNC_BALL:
                     38:       client->dstate = DSTATE_ANY;
                     39:       return(OX_SYNC_BALL);
                     40:     default:
                     41:       errorOxmisc2("oxGet: cannot handle this tag.\n");
                     42:       client->dstate = DSTATE_ERROR;
                     43:       return(-1);
                     44:     }
                     45:     break;
                     46:   case DSTATE_FIRST_SYNC:  /* waiting the first sync ball */
                     47:     /* I need to clear the buffer?? */
                     48:     oxWaitSyncBall(os);
                     49:     client->dstate = DSTATE_ANY;
                     50:     oxSendSyncBall(os);
                     51:     return(OX_SYNC_BALL);
                     52:     break;
                     53:   case DSTATE_WAIT_OX_DATA:  /* waiting a cmo data. */
                     54:     *op = cmoObjectFromStream2(client->datafp2);
                     55:     client->dstate = DSTATE_ANY;
                     56:     *isObj = 1;
                     57:     return(0);
                     58:     break;
                     59:   case DSTATE_ERROR:
                     60:     client->dstate = DSTATE_ERROR;
                     61:     errorOxmisc2("oxGet: dstate == DSTATE_ERROR (error state)\n");
                     62:     return(-1);
                     63:   default:
                     64:     client->dstate = DSTATE_ERROR;
                     65:     errorOxmisc2("oxGet: Unknown state number.");
                     66:   }
                     67:
                     68:   return(-1);
                     69: }
                     70:
                     71: int oxGetFromControl(oxclientp client)
                     72: {
                     73:   int ans = -1;
1.7     ! takayama   74:   AbortIfRFC_101(client);
1.1       maekawa    75:   if (client->cstate != -1) {
                     76:     ans = oxGetResultOfControlInt32(client->controlfd);
                     77:     if (ans != -1) {    client->cstate = 0; }
                     78:     else {client->cstate = -1; }
                     79:   }
                     80:   return(ans);
                     81: }
                     82:
                     83: int oxReq(oxclientp client,int func,struct object ob)
                     84: {
                     85:   struct object *ob1p;
1.6       takayama   86:   SET_MYERROROUT;
1.1       maekawa    87:   /* request to the control channel */
                     88:   if (func == SM_control_reset_connection ||
                     89:       func == SM_control_kill) {
1.7     ! takayama   90:        AbortIfRFC_101(client);
1.1       maekawa    91:     switch(func) {
                     92:     case SM_control_reset_connection:
                     93:       oxReqControlResetConnection(client->controlfd);
                     94:       client->cstate = 1;
                     95:       client->dstate = DSTATE_FIRST_SYNC;
                     96:       break;
                     97:     case SM_control_kill:
                     98:       oxReqControlKill(client->controlfd);
                     99:       client->cstate = 0;
                    100:       client->dstate = DSTATE_ANY;
                    101:       break;
                    102:     }
                    103:     fflush(NULL);
                    104:     return(0);
                    105:   }
                    106:
                    107:   /* request to the data channel */
                    108:   if (client->dstate != DSTATE_ANY) {
                    109:     errorOxmisc2("oxReq: client->dstate != DSTATE_ANY, data channel is not ready to send data.\n");
                    110:     return(-1);
                    111:   }
                    112:   switch(func) {
                    113:   case SM_DUMMY_sendcmo:
                    114:     if (!cmoCheckMathCap(ob,(struct object *)client->mathcapObjp)) {
                    115:       errorOxmisc2("oxReq: your peer does not understand this cmo.\n");
                    116:       return(-1);
                    117:     }
                    118:     oxSendOXheader(client->datafp2,OX_DATA,SerialOX++);
                    119:     cmoObjectToStream2(ob,client->datafp2);
                    120:     client->dstate = DSTATE_ANY;
                    121:     break;
                    122:   case SM_sync_ball:
                    123:     oxSendSyncBall(client->datafp2);
                    124:     client->dstate = DSTATE_ANY; /*  We do not expect the sync ball.*/
                    125:     client->cstate = 0;          /* clear the cstate */
                    126:     break;
                    127:   case SM_popCMO:
                    128:     oxReqPopCMO(client->datafp2);
                    129:     client->dstate = DSTATE_ANY;
                    130:     break;
                    131:   case SM_mathcap:
                    132:     oxReqMathCap(client->datafp2);
                    133:     client->dstate = DSTATE_ANY;
                    134:     break;
                    135:   case SM_setMathCap:
                    136:     /* ob = [(mathcap-obj) [[version num, system name] [sm tags]
                    137:                              ob1                        smtags
1.4       takayama  138:                                     oxtags      [[ox numbers, [cmo numbers]]]
1.1       maekawa   139:                                                     ob3         ob2 */
1.4       takayama  140:    /*     oxtags      [[OX_DATA, [cmo numbers]],[OX_DATA_LOCAL,[opt]],...]*/
1.1       maekawa   141:     {
                    142:       struct object ob1;
                    143:       struct object ob2;
                    144:       struct object ob3;
1.4       takayama  145:       struct object obm;
1.1       maekawa   146:       struct object smtags;
1.4       takayama  147:       struct object oxtags;
                    148:       struct object ox;
1.1       maekawa   149:     int n,i;
                    150:     struct mathCap mathcap;
                    151:
                    152:     if (strcmp(KopString(getoa(ob,0)),"mathcap-object") != 0) {
                    153:       errorOxmisc2("data format error in oxReqSetMathCap");
                    154:       client->dstate = DSTATE_ANY;
                    155:       break;
                    156:     }
1.4       takayama  157:       obm = getoa(ob,1);
                    158:       ob1 = getoa(obm,0);
                    159:       smtags = getoa(obm,1);
                    160:       oxtags = getoa(obm,2);
                    161:       if (smtags.tag != Sarray || oxtags.tag != Sarray) {
                    162:        errorOxmisc2("data format error in oxReqSetMathCap");
                    163:       }
1.1       maekawa   164:       ob1p = (struct object *) sGC_malloc(sizeof(struct object));
                    165:       *ob1p = ob1;
                    166:       mathcap.infop = ob1p;
1.4       takayama  167:
                    168:       n = getoaSize(oxtags);
1.1       maekawa   169:       if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
                    170:       mathcap.oxSize = n;
                    171:       for (i=0; i<n; i++) {
1.4       takayama  172:        ox = getoa(oxtags,i);
                    173:        if (ox.tag != Sarray) {
                    174:          errorOxmisc2("Data format error of the third argument of mathcap.");
                    175:        }
                    176:        mathcap.ox[i] = KopInteger(getoa(ox,0));
                    177:        if (mathcap.ox[i] == OX_DATA) {
                    178:          if (getoaSize(ox) < 2) {
                    179:            errorOxmisc2("Data format error in an entry of the third argument of mathcap.");
                    180:          }
                    181:          ob2 = getoa(ox,1);
                    182:          if (ob2.tag != Sarray) {
                    183:            errorOxmisc2("Data format error in an entry of the third argument of mathcap.");
                    184:          }
                    185:          mathcap.n = getoaSize(ob2);
                    186:          if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
                    187:          for (i=0; i<mathcap.n; i++) {
                    188:            mathcap.cmo[i] = KopInteger(getoa(ob2,i));
                    189:          }
                    190:        }
1.1       maekawa   191:       }
                    192:
                    193:       n = getoaSize(smtags);
                    194:       if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
                    195:       mathcap.smSize = n;
                    196:       for (i=0; i<n; i++) {
                    197:        mathcap.sm[i] = KopInteger(getoa(smtags,i));
                    198:       }
                    199:
                    200:       oxReqSetMathCap(client->datafp2,&mathcap);
                    201:       client->dstate = DSTATE_ANY;
                    202:     }
                    203:     break;
                    204:   case SM_pops:
                    205:     if (ob.tag != Sinteger) {
                    206:       errorOxmisc2("SM_pops : the argument must be an integer.");
                    207:       return(-1);
                    208:     }
                    209:     oxReqPops(client->datafp2, KopInteger(ob));
                    210:     client->dstate = DSTATE_ANY;
                    211:     break;
                    212:   case SM_executeStringByLocalParser:
                    213:     if (ob.tag != Sdollar) {
                    214:       errorOxmisc2("SM_executeStringByLocalParser : the argument must be a string.");
                    215:       return(-1);
                    216:     }
                    217:     oxReqExecuteStringByLocalParser(client->datafp2,KopString(ob));
                    218:     client->dstate = DSTATE_ANY;
                    219:     break;
                    220:   case SM_executeFunction:
                    221:     if (ob.tag != Sdollar) {
                    222:       errorOxmisc2("SM_executeFunction : the argument must be a string.");
                    223:       return(-1);
                    224:     }
                    225:     oxReqExecuteFunction(client->datafp2,KopString(ob));
                    226:     client->dstate = DSTATE_ANY;
                    227:     break;
                    228:   case SM_popString:
                    229:     oxReqPopString(client->datafp2);
                    230:     client->dstate = DSTATE_ANY;
                    231:     break;
                    232:   case SM_evalName:
                    233:     if (ob.tag != Sdollar) {
                    234:       errorOxmisc2("SM_evalName : the argument must be a string.");
                    235:       return(-1);
                    236:     }
                    237:     oxReqEvalName(client->datafp2,KopString(ob));
                    238:     client->dstate = DSTATE_ANY;
                    239:     break;
                    240:   case SM_setName:
                    241:     if (ob.tag != Sdollar) {
                    242:       errorOxmisc2("SM_setName : the argument must be a string.");
                    243:       return(-1);
                    244:     }
                    245:     oxReqSetName(client->datafp2,KopString(ob));
                    246:     client->dstate = DSTATE_ANY;
                    247:     break;
                    248:   case SM_getsp:
                    249:     oxReqSingleOperand(client->datafp2,SM_getsp);
                    250:     client->dstate = DSTATE_ANY;
                    251:     break;
                    252:   case SM_dupErrors:
                    253:     oxReqSingleOperand(client->datafp2,SM_dupErrors);
                    254:     client->dstate = DSTATE_ANY;
                    255:     break;
                    256:   default:
                    257:     fprintf(MyErrorOut,"func=%d ",func);
                    258:     errorOxmisc2("This function is not implemented.");
                    259:     break;
                    260:   }
                    261:   fp2fflush(client->datafp2);
                    262:   return(0);
                    263: }
                    264:
                    265: struct object KoxCreateClient(struct object ip,
                    266:                              struct object portStream,
                    267:                              struct object portControl)
                    268: {
                    269:   struct object rob;
                    270:   oxclientp client;
                    271:   rob.tag = Snull;
                    272:   if (ip.tag != Sdollar) {
                    273:     errorOxmisc2("KoxCreateClient(): The first argument must be a hostname given by a string.");
                    274:     return(rob);
                    275:   }
                    276:   if (portStream.tag == Sdollar) {
                    277:     client = oxCreateClientFile(KopString(ip),KopString(portStream),
                    278:                                "/dev/null","w");
                    279:     if (client == NULL) {
                    280:       errorOxmisc2("KoxCreateClient(): Open error.");
                    281:       return(rob);
                    282:     }
                    283:     rob = newObjectArray(N_OF_CLIENT_FIELDS);
                    284:     oxClientToObject(client,rob);
                    285:     return(rob);
                    286:   }
                    287:
                    288:   if (portStream.tag != Sinteger) {
                    289:     errorOxmisc2("KoxCreateClient(): The second argument must be a port number given in an integer.");
                    290:     return(rob);
                    291:   }
                    292:   if (portControl.tag != Sinteger) {
                    293:     errorOxmisc2("KoxCreateClient(): The third argument must be a port number given in an integer.");
                    294:     return(rob);
                    295:   }
                    296:   client = oxCreateClient(KopString(ip),KopInteger(portStream),KopInteger(portControl));
                    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: static int isItClientObject(struct object ob)
                    307: {
                    308:   int size,i;
                    309:   struct object ee[N_OF_CLIENT_FIELDS];
                    310:   if (ob.tag != Sarray) {
                    311:     return(0);
                    312:   }
                    313:   size = getoaSize(ob);
                    314:   if (size != N_OF_CLIENT_FIELDS) return(0);
                    315:   for (i=0; i<N_OF_CLIENT_FIELDS; i++) {
                    316:     ee[i] = getoa(ob,i);
                    317:   }
                    318:
                    319:   if (ee[0].tag != Sdollar) return(0);
                    320:   if (strcmp(KopString(ee[0]),"client")!=0) return(0);
                    321:
                    322:   if (ee[1].tag != Sfile) return(0);
                    323:   if (strcmp((ee[1]).lc.str,MAGIC2) != 0) return(0);
                    324:
                    325:   for (i=2; i<=9; i++) {
                    326:     if (ee[i].tag != Sinteger) return(0);
                    327:   }
                    328:   return(1);
                    329: }
                    330:
                    331:
                    332: struct object KoxIsThereErrorClient(struct object ob)
                    333: {
                    334:   struct object rob;
                    335:   int ans;
                    336:   int size;
                    337:   oxclient cc;
                    338:   rob.tag = Snull;
                    339:   if (!isItClientObject(ob)) {
                    340:     errorOxmisc2("KoxIsThereErrorClient(): the argument must be an array for client object.");
                    341:     return(rob);
                    342:   }
                    343:   if (oxObjectToClient(ob,&cc) == -1) return(KpoInteger(-1));
                    344:   ans = oxIsThereErrorClient(&cc);
                    345:   return(KpoInteger(ans));
                    346: }
                    347:
                    348: int oxClientToObject(oxclientp client,struct object rob)
                    349: {
                    350:   struct object ob;
                    351:   if (client == NULL) return;
                    352:   /* rob = newObjectArray(N_OF_CLIENT_FIELDS); */
                    353:   if (rob.tag != Sarray) {
                    354:     errorOxmisc2("oxClientToObject(): the second argument must be an array.");
                    355:     return(-1);
                    356:   }
                    357:   if (getoaSize(rob) != N_OF_CLIENT_FIELDS) {
                    358:     errorOxmisc2("oxClientToObject(): the second argument must be an array of size N_OF_CLIENT_FIELDS.");
                    359:     return(-1);
                    360:   }
                    361:
                    362:   ob = KpoString("client");
                    363:   putoa(rob,0,ob);
                    364:
                    365:   ob.tag = Sfile; ob.lc.str = MAGIC2; ob.rc.voidp = (void *)(client->datafp2);
                    366:   putoa(rob,1,ob);
                    367:
                    368:   putoa(rob,2,KpoInteger(client->dataport));
                    369:   putoa(rob,3,KpoInteger(client->controlfd));
                    370:   putoa(rob,4,KpoInteger(client->controlport));
                    371:   putoa(rob,5,KpoInteger(client->dstate));
                    372:   putoa(rob,6,KpoInteger(client->cstate));
                    373:   putoa(rob,7,KpoInteger(client->humanio));
                    374:   putoa(rob,8,KpoInteger(client->id));
                    375:   putoa(rob,9,KpoInteger(client->type));
                    376:   if (client->mathcapObjp == NULL) {
                    377:     putoa(rob,10,NullObject);
                    378:   }else{
                    379:     putoa(rob,10,*((struct object *)(client->mathcapObjp)));
                    380:   }
                    381:   putoa(rob,11,KpoInteger(client->engineByteOrder));
                    382:   putoa(rob,12,KpoInteger(client->controlByteOrder));
                    383:   return(0);
                    384: }
                    385:
                    386: int oxObjectToClient(struct object ob,oxclientp cp)
                    387: {
                    388:   struct object ob1;
                    389:   struct object *obp;
                    390:   if (cp == NULL) {
                    391:     errorOxmisc2("oxObjectToClient(): the second argument is NULL");
                    392:     return(-1);
                    393:   }
                    394:   if (!isItClientObject(ob)) {
                    395:     errorOxmisc2("oxObjectToClient(): the first argument is not client object.");
                    396:     oxInitClient(cp);
                    397:     return(-1);
                    398:   }
                    399:
                    400:   ob1 = getoa(ob,1);
                    401:   cp->datafp2 = (FILE2 *) (ob1.rc.voidp);
                    402:
                    403:   ob1 = getoa(ob,2);
                    404:   cp->dataport = KopInteger(ob1);
                    405:
                    406:   ob1 = getoa(ob,3);
                    407:   cp->controlfd = KopInteger(ob1);
                    408:
                    409:   ob1 = getoa(ob,4);
                    410:   cp->controlport = KopInteger(ob1);
                    411:
                    412:   ob1 = getoa(ob,5);
                    413:   cp->dstate = KopInteger(ob1);
                    414:
                    415:   ob1 = getoa(ob,6);
                    416:   cp->cstate = KopInteger(ob1);
                    417:
                    418:   ob1 = getoa(ob,7);
                    419:   cp->humanio = KopInteger(ob1);
                    420:
                    421:   ob1 = getoa(ob,8);
                    422:   cp->id = KopInteger(ob1);
                    423:
                    424:   ob1 = getoa(ob,9);
                    425:   cp->type = KopInteger(ob1);
                    426:
                    427:   ob1 = getoa(ob,10);
                    428:   if (ob1.tag == Snull) {
                    429:     cp->mathcapObjp = NULL;
                    430:   }else{
                    431:     obp = (struct object *) sGC_malloc(sizeof(struct object));
                    432:     *obp = ob1;
                    433:     cp->mathcapObjp = (void *)obp;
                    434:   }
                    435:   ob1 = getoa(ob,11);
                    436:   cp->engineByteOrder = KopInteger(ob1);
                    437:   ob1 = getoa(ob,12);
                    438:   cp->controlByteOrder = KopInteger(ob1);
                    439:
                    440:
                    441:   return(0);
                    442: }
                    443:
                    444: struct object KoxReq(struct object client,
                    445:                     struct object func,
                    446:                     struct object ob1)
                    447: {
                    448:   int ans;
                    449:   static oxclientp cc1 = NULL;
                    450:   struct object rob;
                    451:   rob.tag = Snull;
                    452:   if (cc1 == NULL) {
                    453:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
                    454:     if (cc1 == NULL) {
                    455:       errorOxmisc2("KoxReq(): no more memory.");
                    456:       return(rob);
                    457:     }
                    458:     oxInitClient(cc1);
                    459:   }
                    460:
                    461:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                    462:   if (cc1 == NULL) {
                    463:     errorOxmisc2("KoxReq(): the first argument must be a client object.");
                    464:     return(rob);
                    465:   }
                    466:   if (func.tag != Sinteger) {
                    467:     errorOxmisc2("KoxReq(): the second argument must be an integer.");
                    468:     return(rob);
                    469:   }
                    470:   ans = oxReq(cc1,KopInteger(func),ob1);
                    471:   /* synchronize cc1 and client. */
                    472:   oxClientToObject(cc1,client);
                    473:
                    474:   return(KpoInteger(ans));
                    475: }
                    476:
                    477: struct object KoxGet(struct object client)
                    478: {
                    479:   int ans,k;
                    480:   static oxclientp cc1 = NULL;
                    481:   struct object rob;
                    482:   rob.tag = Snull;
                    483:   if (cc1 == NULL) {
                    484:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
                    485:     if (cc1 == NULL) {
                    486:       errorOxmisc2("KoxGet(): no more memory.");
                    487:       return(rob);
                    488:     }
                    489:     oxInitClient(cc1);
                    490:   }
                    491:
                    492:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                    493:   if (cc1 == NULL) {
                    494:     errorOxmisc2("KoxGet(): the first argument must be a client object.");
                    495:     return(rob);
                    496:   }
                    497:
                    498:   ans = oxGet(cc1,&rob,&k);
                    499:   /* synchronize cc1 and client. */
                    500:   oxClientToObject(cc1,client);
                    501:
                    502:   if (k) return(rob);
                    503:   else {
                    504:     return(KpoInteger(ans));
                    505:   }
                    506: }
                    507:
                    508: struct object KoxGetFromControl(struct object client)
                    509: {
                    510:   int ans;
                    511:   static oxclientp cc1 = NULL;
                    512:   struct object rob;
                    513:   rob.tag = Snull;
                    514:   if (cc1 == NULL) {
                    515:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
                    516:     if (cc1 == NULL) {
                    517:       errorOxmisc2("KoxGetFromControl(): no more memory.");
                    518:       return(rob);
                    519:     }
                    520:     oxInitClient(cc1);
                    521:   }
                    522:
                    523:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                    524:   if (cc1 == NULL) {
                    525:     errorOxmisc2("KoxGetFromControl(): the first argument must be a client object.");
                    526:     return(rob);
                    527:   }
                    528:
                    529:   ans = oxGetFromControl(cc1);
                    530:   /* synchronize cc1 and client. */
                    531:   oxClientToObject(cc1,client);
                    532:
                    533:   return(KpoInteger(ans));
                    534: }
                    535:
                    536: struct object KoxMultiSelect(struct object oclients,struct object t)
                    537: {
                    538:   static int first = 1;
                    539:   static int csize = 0;
                    540:   static oxclientp *clients = NULL;
                    541:   oxclientp cc1;
                    542:   struct object rob;
                    543:   int i;
                    544:   int tt;
                    545:   struct object ob1;
                    546:   struct object ob2;
                    547:   struct object ob0;
                    548:   int size;
                    549:   int ans;
                    550:   int dataready[1024];
                    551:   int controlready[1024];
                    552:
                    553:   rob.tag = Snull;
                    554:   if (oclients.tag != Sarray) {
                    555:     errorOxmisc2("KoxMultiSelect(): the first argument must be an array.");
                    556:     return(rob);
                    557:   }
                    558:   size = getoaSize(oclients);
                    559:   if (first) {
                    560:     first = 0; csize = size;
                    561:     clients = (oxclientp *)mymalloc(sizeof(oxclientp)*(size+1));
                    562:      if (clients == NULL) {
                    563:       errorOxmisc2("KoxMultiSelect(): no more memory.");
                    564:       return(rob);
                    565:     }
                    566:     for (i=0; i<size; i++) {
                    567:       clients[i] =  (oxclientp) mymalloc(sizeof(oxclient));
                    568:       if (clients[i] == NULL) {
                    569:        errorOxmisc2("KoxMultiSelect(): no more memory.");
                    570:        return(rob);
                    571:       }
                    572:       oxInitClient(clients[i]);
                    573:     }
                    574:   }
                    575:   if (csize < size)  {
                    576:     first = 1;
                    577:     return(KoxMultiSelect(oclients,t));
                    578:   }
                    579:   for (i=0; i<size; i++) {
                    580:     ob0 = getoa(oclients,i);
                    581:     if (oxObjectToClient(ob0,clients[i]) == -1) return(rob);
                    582:   }
                    583:   if (t.tag != Sinteger) {
                    584:     errorOxmisc2("KoxMultiSelect(): the second argument must be an integer.");
                    585:   }
                    586:   tt = KopInteger(t);
                    587:   ans = oxclientMultiSelect(clients,dataready,controlready,size,tt);
                    588:   /* synchronize oclients and clients. */
                    589:   for (i=0; i<size; i++) {
                    590:     ob0 = getoa(oclients,i);
                    591:     oxClientToObject(clients[i],ob0);
                    592:     putoa(oclients,i,ob0);
                    593:   }
                    594:   rob = newObjectArray(3);
                    595:   putoa(rob,0,KpoInteger(ans));
                    596:   ob1 = newObjectArray(size);
                    597:   ob2 = newObjectArray(size);
                    598:   for (i=0; i<size; i++) {
                    599:     putoa(ob1,i,KpoInteger(dataready[i]));
                    600:     putoa(ob2,i,KpoInteger(controlready[i]));
                    601:   }
                    602:   putoa(rob,1,ob1);
                    603:   putoa(rob,2,ob2);
                    604:   return(rob);
                    605: }
                    606:
                    607: struct object KoxWatch(struct object client,struct object f)
                    608: /* f is not used for now. It should be log file. */
                    609: {
                    610:   int ans,k;
                    611:   static oxclientp cc1 = NULL;
                    612:   struct object rob;
1.3       takayama  613:   extern int WatchStream;
1.1       maekawa   614:   rob.tag = Snull;
1.3       takayama  615:   if (client.tag == Sinteger) {
                    616:        if (KopInteger(client)) {
                    617:          WatchStream = 1;
                    618:        }else{
                    619:          WatchStream = 0;
                    620:        }
                    621:        return;
                    622:   }
1.1       maekawa   623:   if (cc1 == NULL) {
                    624:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
                    625:     if (cc1 == NULL) {
                    626:       errorOxmisc2("KoxWatch(): no more memory.");
                    627:       return(rob);
                    628:     }
                    629:     oxInitClient(cc1);
                    630:   }
                    631:
                    632:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                    633:   if (cc1 == NULL) {
                    634:     errorOxmisc2("KoxWatch(): the first argument must be a client object.");
                    635:     return(rob);
                    636:   }
                    637:
                    638:   k = fp2watch(cc1->datafp2,stdout);
                    639:   /* synchronize cc1 and client. */
                    640:   oxClientToObject(cc1,client);
                    641:
                    642:   return(KpoInteger(ans));
                    643: }
                    644:
                    645:
                    646: struct object KoxCloseClient(struct object client) {
                    647:   oxclientp cc1 = NULL;
                    648:   oxclient cc;
                    649:   struct object rob;
                    650:   rob.tag = Snull;
                    651:   cc1  = &cc;
                    652:   if (oxObjectToClient(client,cc1) == -1) return(rob);
                    653:   if (cc1 == NULL) {
                    654:     errorOxmisc2("KoxCloseClient(): the first argument must be a client object.");
                    655:     return(rob);
                    656:   }
                    657:
                    658:   fp2fflush(cc1->datafp2);
                    659:   if (cc1->humanio) {
                    660:     /* Do not close the file. */
                    661:     return(KpoInteger(0));
                    662:   }
                    663:   switch (cc1->type) {
                    664:   case CLIENT_SOCKET:
                    665:     fp2fclose(cc1->datafp2);
                    666:     close(cc1->controlfd);
                    667:     break;
                    668:   case CLIENT_FILE:
                    669:     fp2fclose(cc1->datafp2);
                    670:     close(cc1->controlfd);
                    671:     break;
                    672:   default:
                    673:     errorOxmisc2("Unknown client->type\n");
                    674:     break;
                    675:   }
                    676:   return(KpoInteger(0));
                    677:
                    678: }
                    679:
                    680: static int cmoCheck00(struct object obj,int cmo[], int n) {
                    681:   int i,j,m;
                    682:   int ttt;
                    683: #define CHECK00_N  4098      /* look up stackm.h and kclass.h */
                    684:   static int typeTrans[CHECK00_N];
                    685:   static int init = 0;
1.5       takayama  686:   /* if n == 0, report the cmo tag of the object obj.
                    687:         If it cannot be translated to cmo, then return -1. */
                    688:
1.1       maekawa   689:   if (!init) {
                    690:     for (i=0; i<CHECK00_N; i++) {
                    691:       typeTrans[i] = 0;  /* unknown cmo number */
                    692:     }
                    693:     typeTrans[Snull] = CMO_NULL;
                    694:     typeTrans[Sinteger] = CMO_INT32;
                    695:     typeTrans[Sdollar] = CMO_STRING;
                    696:     if (OxVersion >= 199907170) {
                    697:       typeTrans[SuniversalNumber] = CMO_ZZ;
                    698:     }else{
                    699:       typeTrans[SuniversalNumber] = CMO_ZZ_OLD;
                    700:     }
                    701:     typeTrans[Sarray] = CMO_LIST;
                    702:     /* typeTrans[Spoly] = CMO_DMS;  */
                    703:     typeTrans[Spoly] = CMO_DISTRIBUTED_POLYNOMIAL;
                    704:     typeTrans[Sdouble] = CMO_64BIT_MACHINE_DOUBLE;
                    705:     typeTrans[CLASSNAME_ERROR_PACKET]   = CMO_ERROR2;
                    706:     typeTrans[CLASSNAME_mathcap] = CMO_MATHCAP;
                    707:     typeTrans[CLASSNAME_indeterminate] = CMO_INDETERMINATE;
                    708:     typeTrans[CLASSNAME_tree] = CMO_TREE;
                    709:     typeTrans[CLASSNAME_recursivePolynomial] = CMO_RECURSIVE_POLYNOMIAL;
                    710:     typeTrans[CLASSNAME_polynomialInOneVariable] = CMO_POLYNOMIAL_IN_ONE_VARIABLE;
                    711:     init = 1;
                    712:   }
                    713:   ttt = typeTrans[obj.tag];
                    714:   if (obj.tag == Sclass) {
                    715:     ttt = typeTrans[ectag(obj)];
                    716:   }
1.5       takayama  717:   /* Only report the cmo tag. */
                    718:   if (n == 0) {
                    719:        if (ttt == 0) return(-1);
                    720:        else return(ttt);
                    721:   }
1.1       maekawa   722:
                    723:   for (i=0; i<n; i++) {
                    724:     if (ttt == cmo[i]) {
                    725:       if (ttt != CMO_LIST) return(1);
                    726:       else {
                    727:        m = getoaSize(obj);
                    728:        for (j=0; j<m; j++) {
                    729:          if (!cmoCheck00(getoa(obj,j),cmo,n)) return(0);
                    730:        }
                    731:        return(1);
                    732:       }
                    733:     }
                    734:   }
                    735:   if (DebugMathCap) {
                    736:     if (DebugMathCap && 1) {
                    737:       fprintf(stderr,"Type translation table (internal object tag --> CMO tag)\n");
                    738:       for (i=0; i<20; i++) {
                    739:        printf("%d ", typeTrans[i]);
                    740:       }
                    741:       printf("\n");
                    742:     }
                    743:     fprintf(stderr,"The type of the argument object in sm1 is %d.\n",obj.tag);
                    744:     fprintf(stderr,"The type of the argument object in CMO is %d.\n",ttt);
                    745:     fprintf(stderr,"Available CMO tags in mathcap= %d elements : [ ",n);
                    746:     for (i=0; i<n; i++) {
                    747:       fprintf(stderr," %d ",cmo[i]);
                    748:     }
                    749:     fprintf(stderr," ] \n");
                    750:   }
                    751:   return(0);
                    752: }
                    753:
                    754: int cmoCheckMathCap(struct object obj, struct object *obp)
                    755: {
                    756:   struct object mathcap;
                    757:   struct object cmolist;
1.2       takayama  758:   struct object mathcapMain;
1.4       takayama  759:   struct object mathcapThird;
                    760:   struct object ox;
                    761:   struct object oxtag;
1.2       takayama  762:   struct object ob0;
1.4       takayama  763:   int oxsize;
1.1       maekawa   764:   int n;
                    765:   int i;
                    766: #define CMO_CHECK_MATH_CAP_LIST_SIZE 1024
                    767:   int cmo[CMO_CHECK_MATH_CAP_LIST_SIZE];
                    768:   if (obp == NULL) return(1);
1.2       takayama  769:   /* printObject(*obp,0,stderr); for debug*/
1.1       maekawa   770:   if (obp->tag != Sarray) {
                    771:     fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    772:     printObject(*obp,0,stderr);
                    773:     fprintf(stderr,"\n");
                    774:     errorOxmisc2("cmoCheckMathCap: format error in the client->mathcapObjp field.\n");
                    775:   }
                    776:   mathcap = *obp;
1.2       takayama  777:   /* Example of mathcap
                    778:     [    $mathcap-object$ ,
                    779:        [    [    199909080 , $Ox_system=ox_sm1.plain$ , $Version=2.991106$ ,
                    780:                  $HOSTTYPE=i386$ ]  ,
                    781:             [    262 , 263 , 264 , 265 , 266 , 268 , 269 , 272 , 273 , 275 ,
                    782:                  276 ]  ,
1.4       takayama  783:             [    [    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  784:   */
                    785:
1.1       maekawa   786:   n = getoaSize(mathcap);
                    787:   if (n < 2) {
                    788:     fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    789:     printObject(*obp,0,stderr);
                    790:     fprintf(stderr,"\n");
                    791:     errorOxmisc2("cmoCheckMathCap: length of mathcap is wrong in the client->mathcapObjp field.\n");
                    792:   }
1.2       takayama  793:   ob0 = getoa(mathcap,0);
                    794:   if (ob0.tag != Sdollar) {
                    795:     fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    796:     printObject(*obp,0,stderr);
                    797:     fprintf(stderr,"\n");
                    798:     errorOxmisc2("cmoCheckMathCap: The first field must be the string mathcap-object.\n");
                    799:   }
                    800:   if (strcmp(KopString(ob0),"mathcap-object") != 0) {
                    801:     fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    802:     printObject(*obp,0,stderr);
                    803:     fprintf(stderr,"\n");
                    804:     errorOxmisc2("cmoCheckMathCap: The mathcap must be of the form [(mathcap-object) [...]]\n");
                    805:   }
                    806:
1.1       maekawa   807:   /* I should check
1.2       takayama  808:          getoa(getoa(mathcap,1),2)
1.1       maekawa   809:      contains OX_DATA.
                    810:      It has not yet implemented.
                    811:   */
1.2       takayama  812:   mathcapMain = getoa(mathcap,1);
                    813:   if (mathcapMain.tag != Sarray) {
                    814:     fprintf(stderr,"cmoCheckMathCap: mathcap[1] is \n");
                    815:     printObject(mathcapMain,0,stderr);
                    816:     fprintf(stderr,"\n");
                    817:     errorOxmisc2("cmoCheckMathCap: format error in the (client->mathcapObjp)[1] field. It should be an array.\n");
                    818:   }
                    819:   if (getoaSize(mathcapMain) < 3) {
                    820:     fprintf(stderr,"cmoCheckMathCap: mathcap[1] is \n");
                    821:     printObject(mathcapMain,0,stderr);
                    822:     fprintf(stderr,"\n");
                    823:     errorOxmisc2("cmoCheckMathCap: format error in the (client->mathcapObjp)[1] field. It should be an array of which length is more than 2.\n");
                    824:   }
1.4       takayama  825:   mathcapThird = getoa(mathcapMain,2);
                    826:   oxsize = getoaSize(mathcapThird);
                    827:   for (i=0; i<oxsize; i++) {
                    828:     ox = getoa(mathcapThird,i);
                    829:     if (ox.tag != Sarray) {
                    830:       fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    831:       printObject(*obp,0,stderr);
                    832:       fprintf(stderr,"\n");
                    833:       errorOxmisc2("cmoCheckMathCap: the third element of mathcap is a list of lists.");
                    834:     }
                    835:     if (getoaSize(ox) != 0) {
                    836:       oxtag = getoa(ox,0);
                    837:       if (oxtag.tag != Sinteger) {
                    838:        fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    839:        printObject(*obp,0,stderr);
                    840:        fprintf(stderr,"\n");
                    841:        errorOxmisc2("cmoCheckMathCap: the third element of mathcap must be [OX_DATA_xxx, [  ]].");
                    842:       }
                    843:       if (KopInteger(oxtag) == OX_DATA) {
                    844:        if (getoaSize(ox) > 1) {
                    845:          cmolist = getoa(ox,1);
                    846:          if (cmolist.tag != Sarray) {
                    847:            fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    848:            printObject(*obp,0,stderr);
                    849:            fprintf(stderr,"\n");
                    850:            errorOxmisc2("cmoCheckMathCap: mathcap[1] must be an array of integers.\n");
                    851:          }
                    852:          n = getoaSize(cmolist);
                    853:          if (n > CMO_CHECK_MATH_CAP_LIST_SIZE) {
                    854:            errorOxmisc2("cmoCheckMathCap: Too big cmo list.\n");
                    855:          }
                    856:          for (i=0; i<n; i++) {
                    857:            cmo[i] = KopInteger(getoa(cmolist,i));
                    858:          }
                    859:        }else{
                    860:          fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
                    861:          printObject(*obp,0,stderr);
                    862:          fprintf(stderr,"\nox=");
                    863:          printObject(ox,0,stderr);
                    864:          errorOxmisc2("cmoCheckMathCap: [OX_DATA, cmolist]");
                    865:        }
                    866:       }
                    867:     }
1.1       maekawa   868:   }
                    869:   return(cmoCheck00(obj,cmo,n));
                    870: }
                    871:
                    872:
                    873: struct object KoxGenPortFile(void) {
                    874:   struct object ob;
                    875:   ob = KpoString(oxGenPortFile());
                    876:   return(ob);
                    877: }
                    878: void KoxRemovePortFile(void) {
                    879:   oxRemovePortFile();
                    880: }
                    881:
                    882: void oxPushMathCap(struct mathCap *mathcap)
                    883: {
                    884:   struct object rob;
                    885:   rob = newMathCap(mathcap);
                    886:   Kpush(rob);
                    887: }
                    888:
                    889: struct object KoxGenPass(void) {
                    890:   struct object rob;
                    891:   rob = KpoString(oxGenPass());
                    892:   return(rob);
                    893: }
                    894:
                    895: struct object KoxGetPort(struct object host)
                    896: {
                    897:   struct object rob;
                    898:   int fdStream, fdControl;
                    899:   int portStream, portControl;
                    900:   extern int OpenedSocket;
                    901:   char *sname;
                    902:   rob = NullObject;
                    903:   if (host.tag != Sdollar) {
                    904:     errorOxmisc2("KoxGetPort: argument is not a string.");
                    905:     return(rob);
                    906:   }
                    907:   sname = KopString(host);
                    908:   fdControl = socketOpen(sname,0);
                    909:   portControl = OpenedSocket;
                    910:   fdStream = socketOpen(sname,0);
                    911:   portStream = OpenedSocket;
                    912:   rob = newObjectArray(4);
                    913:   putoa(rob,0,KpoInteger(fdStream));
                    914:   putoa(rob,1,KpoInteger(portStream));
                    915:   putoa(rob,2,KpoInteger(fdControl));
                    916:   putoa(rob,3,KpoInteger(portControl));
                    917:   return(rob);
                    918: }
                    919:
                    920: struct object KoxCreateClient2(struct object peer,
                    921:                               struct object ipmask,
                    922:                               struct object pass)
                    923: {
                    924:   struct object rob;
                    925:   oxclientp client;
                    926:   int fdStream, portStream, fdControl, portControl;
                    927:   int i;
                    928:   struct object ob1;
                    929:   rob.tag = Snull;
                    930:   if (peer.tag != Sarray) {
                    931:     errorOxmisc2("KoxCreateClient2(): The first argument must be an array [fdStream, portStream, fdControl, portControl]");
                    932:     return(rob);
                    933:   }
                    934:   if (getoaSize(peer) != 4) {
                    935:     errorOxmisc2("KoxCreateClient2(): The first argument must be an array [fdStream, portStream, fdControl, portControl] of size 4.");
                    936:     return(rob);
                    937:   }
                    938:   for (i=0; i<4; i++) {
                    939:     ob1 = getoa(peer,i);
                    940:     if (ob1.tag != Sinteger) {
                    941:       errorOxmisc2("KoxCreateClient2(): The element of the first argument must be an integer.");
                    942:     }
                    943:   }
                    944:   fdStream = KopInteger(getoa(peer,0));
                    945:   portStream = KopInteger(getoa(peer,1));
                    946:   fdControl = KopInteger(getoa(peer,2));
                    947:   portControl = KopInteger(getoa(peer,3));
                    948:
                    949:   if (ipmask.tag != Sinteger) {
                    950:     errorOxmisc2("KoxCreateClient2(): ipmask must be an integer.");
                    951:   }
                    952:   if (pass.tag != Sdollar) {
                    953:     errorOxmisc2("KoxCreateClient2(): pass must be a string.");
                    954:   }
                    955:
                    956:   client = oxCreateClient2(fdStream, portStream, fdControl, portControl,
                    957:                           KopInteger(ipmask), KopString(pass));
                    958:   if (client == NULL) {
                    959:     errorOxmisc2("KoxCreateClient2(): Open error.");
                    960:     return(rob);
                    961:   }
                    962:   rob = newObjectArray(N_OF_CLIENT_FIELDS);
                    963:   oxClientToObject(client,rob);
                    964:   return(rob);
1.5       takayama  965: }
                    966:
                    967: int KgetCmoTagOfObject(struct object obj) {
                    968:   int k;
                    969:   k=cmoCheck00(obj,(int *)NULL,0);
                    970:   return(k);
1.1       maekawa   971: }
                    972:
                    973: errorOxmisc2(char *s) {
1.6       takayama  974:   SET_MYERROROUT;
1.1       maekawa   975:   fprintf(MyErrorOut,"error in oxmisc2.c: %s\n",s);
                    976:   errorKan1("%s\n","  ");
1.7     ! takayama  977: }
        !           978:
        !           979: struct object KoxPushCMD(struct object client,struct object cmd) {
        !           980:   int ans;
        !           981:   static oxclientp cc1 = NULL;
        !           982:   struct object rob;
        !           983:   rob.tag = Snull;
        !           984:   if (cc1 == NULL) {
        !           985:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
        !           986:     if (cc1 == NULL) {
        !           987:       errorOxmisc2("KoxReq(): no more memory.");
        !           988:       return(rob);
        !           989:     }
        !           990:     oxInitClient(cc1);  /* BUG: is it fine? */
        !           991:   }
        !           992:
        !           993:   if (oxObjectToClient(client,cc1) == -1) return(rob);
        !           994:   if (cc1 == NULL) {
        !           995:     errorOxmisc2("KoxReq(): the first argument must be a client object.");
        !           996:     return(rob);
        !           997:   }
        !           998:   if (cmd.tag != Sinteger) {
        !           999:     errorOxmisc2("KoxReq(): the second argument must be an integer.");
        !          1000:     return(rob);
        !          1001:   }
        !          1002:   /* BUG: check the mathcap */
        !          1003:   oxSendOXheader(cc1->datafp2,OX_COMMAND,SerialOX++);
        !          1004:   oxSendInt32(cc1->datafp2,KopInteger(cmd));
        !          1005:   /* synchronize cc1 and client. */
        !          1006:   oxClientToObject(cc1,client);
        !          1007:   return(cmd);
        !          1008: }
        !          1009:
        !          1010: struct object KoxPushCMO(struct object client,struct object ob) {
        !          1011:   int ans;
        !          1012:   static oxclientp cc1 = NULL;
        !          1013:   struct object rob;
        !          1014:   rob.tag = Snull;
        !          1015:   if (cc1 == NULL) {
        !          1016:     cc1 = (oxclientp) mymalloc(sizeof(oxclient));
        !          1017:     if (cc1 == NULL) {
        !          1018:       errorOxmisc2("KoxReq(): no more memory.");
        !          1019:       return(rob);
        !          1020:     }
        !          1021:     oxInitClient(cc1);  /* BUG: is it fine? */
        !          1022:   }
        !          1023:
        !          1024:   if (oxObjectToClient(client,cc1) == -1) return(rob);
        !          1025:   if (cc1 == NULL) {
        !          1026:     errorOxmisc2("KoxReq(): the first argument must be a client object.");
        !          1027:     return(rob);
        !          1028:   }
        !          1029:
        !          1030:   /* request to the data channel */
        !          1031:   if (cc1->dstate != DSTATE_ANY) {
        !          1032:     errorOxmisc2("oxPushCMO: cc1->dstate != DSTATE_ANY, data channel is not ready to send data.\n");
        !          1033:     return(rob);
        !          1034:   }
        !          1035:
        !          1036:   if (!cmoCheckMathCap(ob,(struct object *)cc1->mathcapObjp)) {
        !          1037:        errorOxmisc2("oxPushCMO: your peer does not understand this cmo.\n");
        !          1038:        return(rob);
        !          1039:   }
        !          1040:   oxSendOXheader(cc1->datafp2,OX_DATA,SerialOX++);
        !          1041:   cmoObjectToStream2(ob,cc1->datafp2);
        !          1042:   /* synchronize cc1 and client. */
        !          1043:   oxClientToObject(cc1,client);
        !          1044:   return(ob);
1.1       maekawa  1045: }

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