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>