Annotation of OpenXM/src/kan96xx/plugin/oxmisc2.c, Revision 1.9
1.9 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/plugin/oxmisc2.c,v 1.8 2000/12/03 08:19:55 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)
20: /* This method should be synchronized. */
21: /* oxGet is a function for client. */
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.7 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]
138: ob1 smtags
1.4 takayama 139: oxtags [[ox numbers, [cmo numbers]]]
1.1 maekawa 140: ob3 ob2 */
1.4 takayama 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.1 maekawa 150: int n,i;
151: struct mathCap mathcap;
152:
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) {
163: errorOxmisc2("data format error in oxReqSetMathCap");
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.4 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++) {
198: mathcap.sm[i] = KopInteger(getoa(smtags,i));
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,
267: struct object portStream,
268: struct object portControl)
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),
279: "/dev/null","w");
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);
304: return(rob);
305: }
306:
307: static int isItClientObject(struct object ob)
308: {
309: int size,i;
310: struct object ee[N_OF_CLIENT_FIELDS];
311: if (ob.tag != Sarray) {
312: return(0);
313: }
314: size = getoaSize(ob);
315: if (size != N_OF_CLIENT_FIELDS) return(0);
316: for (i=0; i<N_OF_CLIENT_FIELDS; i++) {
317: ee[i] = getoa(ob,i);
318: }
319:
320: if (ee[0].tag != Sdollar) return(0);
321: if (strcmp(KopString(ee[0]),"client")!=0) return(0);
322:
323: if (ee[1].tag != Sfile) return(0);
324: if (strcmp((ee[1]).lc.str,MAGIC2) != 0) return(0);
325:
326: for (i=2; i<=9; i++) {
327: if (ee[i].tag != Sinteger) return(0);
328: }
329: return(1);
330: }
331:
332:
333: struct object KoxIsThereErrorClient(struct object ob)
334: {
335: struct object rob;
336: int ans;
337: int size;
338: oxclient cc;
339: rob.tag = Snull;
340: if (!isItClientObject(ob)) {
341: errorOxmisc2("KoxIsThereErrorClient(): the argument must be an array for client object.");
342: return(rob);
343: }
344: if (oxObjectToClient(ob,&cc) == -1) return(KpoInteger(-1));
345: ans = oxIsThereErrorClient(&cc);
346: return(KpoInteger(ans));
347: }
348:
349: int oxClientToObject(oxclientp client,struct object rob)
350: {
351: struct object ob;
352: if (client == NULL) return;
353: /* rob = newObjectArray(N_OF_CLIENT_FIELDS); */
354: if (rob.tag != Sarray) {
355: errorOxmisc2("oxClientToObject(): the second argument must be an array.");
356: return(-1);
357: }
358: if (getoaSize(rob) != N_OF_CLIENT_FIELDS) {
359: errorOxmisc2("oxClientToObject(): the second argument must be an array of size N_OF_CLIENT_FIELDS.");
360: return(-1);
361: }
362:
363: ob = KpoString("client");
364: putoa(rob,0,ob);
365:
366: ob.tag = Sfile; ob.lc.str = MAGIC2; ob.rc.voidp = (void *)(client->datafp2);
367: putoa(rob,1,ob);
368:
369: putoa(rob,2,KpoInteger(client->dataport));
370: putoa(rob,3,KpoInteger(client->controlfd));
371: putoa(rob,4,KpoInteger(client->controlport));
372: putoa(rob,5,KpoInteger(client->dstate));
373: putoa(rob,6,KpoInteger(client->cstate));
374: putoa(rob,7,KpoInteger(client->humanio));
375: putoa(rob,8,KpoInteger(client->id));
376: putoa(rob,9,KpoInteger(client->type));
377: if (client->mathcapObjp == NULL) {
378: putoa(rob,10,NullObject);
379: }else{
380: putoa(rob,10,*((struct object *)(client->mathcapObjp)));
381: }
382: putoa(rob,11,KpoInteger(client->engineByteOrder));
383: putoa(rob,12,KpoInteger(client->controlByteOrder));
384: return(0);
385: }
386:
387: int oxObjectToClient(struct object ob,oxclientp cp)
388: {
389: struct object ob1;
390: struct object *obp;
391: if (cp == NULL) {
392: errorOxmisc2("oxObjectToClient(): the second argument is NULL");
393: return(-1);
394: }
395: if (!isItClientObject(ob)) {
396: errorOxmisc2("oxObjectToClient(): the first argument is not client object.");
397: oxInitClient(cp);
398: return(-1);
399: }
400:
401: ob1 = getoa(ob,1);
402: cp->datafp2 = (FILE2 *) (ob1.rc.voidp);
403:
404: ob1 = getoa(ob,2);
405: cp->dataport = KopInteger(ob1);
406:
407: ob1 = getoa(ob,3);
408: cp->controlfd = KopInteger(ob1);
409:
410: ob1 = getoa(ob,4);
411: cp->controlport = KopInteger(ob1);
412:
413: ob1 = getoa(ob,5);
414: cp->dstate = KopInteger(ob1);
415:
416: ob1 = getoa(ob,6);
417: cp->cstate = KopInteger(ob1);
418:
419: ob1 = getoa(ob,7);
420: cp->humanio = KopInteger(ob1);
421:
422: ob1 = getoa(ob,8);
423: cp->id = KopInteger(ob1);
424:
425: ob1 = getoa(ob,9);
426: cp->type = KopInteger(ob1);
427:
428: ob1 = getoa(ob,10);
429: if (ob1.tag == Snull) {
430: cp->mathcapObjp = NULL;
431: }else{
432: obp = (struct object *) sGC_malloc(sizeof(struct object));
433: *obp = ob1;
434: cp->mathcapObjp = (void *)obp;
435: }
436: ob1 = getoa(ob,11);
437: cp->engineByteOrder = KopInteger(ob1);
438: ob1 = getoa(ob,12);
439: cp->controlByteOrder = KopInteger(ob1);
440:
441:
442: return(0);
443: }
444:
445: struct object KoxReq(struct object client,
446: struct object func,
447: struct object ob1)
448: {
449: int ans;
450: static oxclientp cc1 = NULL;
451: struct object rob;
452: rob.tag = Snull;
453: if (cc1 == NULL) {
454: cc1 = (oxclientp) mymalloc(sizeof(oxclient));
455: if (cc1 == NULL) {
456: errorOxmisc2("KoxReq(): no more memory.");
457: return(rob);
458: }
459: oxInitClient(cc1);
460: }
461:
462: if (oxObjectToClient(client,cc1) == -1) return(rob);
463: if (cc1 == NULL) {
464: errorOxmisc2("KoxReq(): the first argument must be a client object.");
465: return(rob);
466: }
467: if (func.tag != Sinteger) {
468: errorOxmisc2("KoxReq(): the second argument must be an integer.");
469: return(rob);
470: }
471: ans = oxReq(cc1,KopInteger(func),ob1);
472: /* synchronize cc1 and client. */
473: oxClientToObject(cc1,client);
474:
475: return(KpoInteger(ans));
476: }
477:
478: struct object KoxGet(struct object client)
479: {
480: int ans,k;
481: static oxclientp cc1 = NULL;
482: struct object rob;
483: rob.tag = Snull;
484: if (cc1 == NULL) {
485: cc1 = (oxclientp) mymalloc(sizeof(oxclient));
486: if (cc1 == NULL) {
487: errorOxmisc2("KoxGet(): no more memory.");
488: return(rob);
489: }
490: oxInitClient(cc1);
491: }
492:
493: if (oxObjectToClient(client,cc1) == -1) return(rob);
494: if (cc1 == NULL) {
495: errorOxmisc2("KoxGet(): the first argument must be a client object.");
496: return(rob);
497: }
498:
499: ans = oxGet(cc1,&rob,&k);
500: /* synchronize cc1 and client. */
501: oxClientToObject(cc1,client);
502:
503: if (k) return(rob);
504: else {
505: return(KpoInteger(ans));
506: }
507: }
508:
509: struct object KoxGetFromControl(struct object client)
510: {
511: int ans;
512: static oxclientp cc1 = NULL;
513: struct object rob;
514: rob.tag = Snull;
515: if (cc1 == NULL) {
516: cc1 = (oxclientp) mymalloc(sizeof(oxclient));
517: if (cc1 == NULL) {
518: errorOxmisc2("KoxGetFromControl(): no more memory.");
519: return(rob);
520: }
521: oxInitClient(cc1);
522: }
523:
524: if (oxObjectToClient(client,cc1) == -1) return(rob);
525: if (cc1 == NULL) {
526: errorOxmisc2("KoxGetFromControl(): the first argument must be a client object.");
527: return(rob);
528: }
529:
530: ans = oxGetFromControl(cc1);
531: /* synchronize cc1 and client. */
532: oxClientToObject(cc1,client);
533:
534: return(KpoInteger(ans));
535: }
536:
537: struct object KoxMultiSelect(struct object oclients,struct object t)
538: {
539: static int first = 1;
540: static int csize = 0;
541: static oxclientp *clients = NULL;
542: oxclientp cc1;
543: struct object rob;
544: int i;
545: int tt;
546: struct object ob1;
547: struct object ob2;
548: struct object ob0;
549: int size;
550: int ans;
551: int dataready[1024];
552: int controlready[1024];
553:
554: rob.tag = Snull;
555: if (oclients.tag != Sarray) {
556: errorOxmisc2("KoxMultiSelect(): the first argument must be an array.");
557: return(rob);
558: }
559: size = getoaSize(oclients);
560: if (first) {
561: first = 0; csize = size;
562: clients = (oxclientp *)mymalloc(sizeof(oxclientp)*(size+1));
563: if (clients == NULL) {
564: errorOxmisc2("KoxMultiSelect(): no more memory.");
565: return(rob);
566: }
567: for (i=0; i<size; i++) {
568: clients[i] = (oxclientp) mymalloc(sizeof(oxclient));
569: if (clients[i] == NULL) {
570: errorOxmisc2("KoxMultiSelect(): no more memory.");
571: return(rob);
572: }
573: oxInitClient(clients[i]);
574: }
575: }
576: if (csize < size) {
577: first = 1;
578: return(KoxMultiSelect(oclients,t));
579: }
580: for (i=0; i<size; i++) {
581: ob0 = getoa(oclients,i);
582: if (oxObjectToClient(ob0,clients[i]) == -1) return(rob);
583: }
584: if (t.tag != Sinteger) {
585: errorOxmisc2("KoxMultiSelect(): the second argument must be an integer.");
586: }
587: tt = KopInteger(t);
588: ans = oxclientMultiSelect(clients,dataready,controlready,size,tt);
589: /* synchronize oclients and clients. */
590: for (i=0; i<size; i++) {
591: ob0 = getoa(oclients,i);
592: oxClientToObject(clients[i],ob0);
593: putoa(oclients,i,ob0);
594: }
595: rob = newObjectArray(3);
596: putoa(rob,0,KpoInteger(ans));
597: ob1 = newObjectArray(size);
598: ob2 = newObjectArray(size);
599: for (i=0; i<size; i++) {
600: putoa(ob1,i,KpoInteger(dataready[i]));
601: putoa(ob2,i,KpoInteger(controlready[i]));
602: }
603: putoa(rob,1,ob1);
604: putoa(rob,2,ob2);
605: return(rob);
606: }
607:
608: struct object KoxWatch(struct object client,struct object f)
609: /* f is not used for now. It should be log file. */
610: {
611: int ans,k;
612: static oxclientp cc1 = NULL;
613: struct object rob;
1.3 takayama 614: extern int WatchStream;
1.1 maekawa 615: rob.tag = Snull;
1.3 takayama 616: if (client.tag == Sinteger) {
617: if (KopInteger(client)) {
618: WatchStream = 1;
619: }else{
620: WatchStream = 0;
621: }
622: return;
623: }
1.1 maekawa 624: if (cc1 == NULL) {
625: cc1 = (oxclientp) mymalloc(sizeof(oxclient));
626: if (cc1 == NULL) {
627: errorOxmisc2("KoxWatch(): no more memory.");
628: return(rob);
629: }
630: oxInitClient(cc1);
631: }
632:
633: if (oxObjectToClient(client,cc1) == -1) return(rob);
634: if (cc1 == NULL) {
635: errorOxmisc2("KoxWatch(): the first argument must be a client object.");
636: return(rob);
637: }
638:
639: k = fp2watch(cc1->datafp2,stdout);
640: /* synchronize cc1 and client. */
641: oxClientToObject(cc1,client);
642:
643: return(KpoInteger(ans));
644: }
645:
646:
647: struct object KoxCloseClient(struct object client) {
648: oxclientp cc1 = NULL;
649: oxclient cc;
650: struct object rob;
651: rob.tag = Snull;
652: cc1 = &cc;
653: if (oxObjectToClient(client,cc1) == -1) return(rob);
654: if (cc1 == NULL) {
655: errorOxmisc2("KoxCloseClient(): the first argument must be a client object.");
656: return(rob);
657: }
658:
659: fp2fflush(cc1->datafp2);
660: if (cc1->humanio) {
661: /* Do not close the file. */
662: return(KpoInteger(0));
663: }
664: switch (cc1->type) {
665: case CLIENT_SOCKET:
666: fp2fclose(cc1->datafp2);
667: close(cc1->controlfd);
668: break;
669: case CLIENT_FILE:
670: fp2fclose(cc1->datafp2);
671: close(cc1->controlfd);
672: break;
673: default:
674: errorOxmisc2("Unknown client->type\n");
675: break;
676: }
677: return(KpoInteger(0));
678:
679: }
680:
681: static int cmoCheck00(struct object obj,int cmo[], int n) {
682: int i,j,m;
683: int ttt;
684: #define CHECK00_N 4098 /* look up stackm.h and kclass.h */
685: static int typeTrans[CHECK00_N];
686: static int init = 0;
1.5 takayama 687: /* if n == 0, report the cmo tag of the object obj.
688: If it cannot be translated to cmo, then return -1. */
689:
1.1 maekawa 690: if (!init) {
691: for (i=0; i<CHECK00_N; i++) {
692: typeTrans[i] = 0; /* unknown cmo number */
693: }
694: typeTrans[Snull] = CMO_NULL;
695: typeTrans[Sinteger] = CMO_INT32;
696: typeTrans[Sdollar] = CMO_STRING;
697: if (OxVersion >= 199907170) {
698: typeTrans[SuniversalNumber] = CMO_ZZ;
699: }else{
700: typeTrans[SuniversalNumber] = CMO_ZZ_OLD;
701: }
702: typeTrans[Sarray] = CMO_LIST;
703: /* typeTrans[Spoly] = CMO_DMS; */
704: typeTrans[Spoly] = CMO_DISTRIBUTED_POLYNOMIAL;
705: typeTrans[Sdouble] = CMO_64BIT_MACHINE_DOUBLE;
706: typeTrans[CLASSNAME_ERROR_PACKET] = CMO_ERROR2;
707: typeTrans[CLASSNAME_mathcap] = CMO_MATHCAP;
708: typeTrans[CLASSNAME_indeterminate] = CMO_INDETERMINATE;
709: typeTrans[CLASSNAME_tree] = CMO_TREE;
710: typeTrans[CLASSNAME_recursivePolynomial] = CMO_RECURSIVE_POLYNOMIAL;
711: typeTrans[CLASSNAME_polynomialInOneVariable] = CMO_POLYNOMIAL_IN_ONE_VARIABLE;
712: init = 1;
713: }
714: ttt = typeTrans[obj.tag];
715: if (obj.tag == Sclass) {
716: ttt = typeTrans[ectag(obj)];
717: }
1.5 takayama 718: /* Only report the cmo tag. */
719: if (n == 0) {
720: if (ttt == 0) return(-1);
721: else return(ttt);
722: }
1.1 maekawa 723:
724: for (i=0; i<n; i++) {
725: if (ttt == cmo[i]) {
726: if (ttt != CMO_LIST) return(1);
727: else {
728: m = getoaSize(obj);
729: for (j=0; j<m; j++) {
730: if (!cmoCheck00(getoa(obj,j),cmo,n)) return(0);
731: }
732: return(1);
733: }
734: }
735: }
736: if (DebugMathCap) {
737: if (DebugMathCap && 1) {
738: fprintf(stderr,"Type translation table (internal object tag --> CMO tag)\n");
739: for (i=0; i<20; i++) {
740: printf("%d ", typeTrans[i]);
741: }
742: printf("\n");
743: }
744: fprintf(stderr,"The type of the argument object in sm1 is %d.\n",obj.tag);
745: fprintf(stderr,"The type of the argument object in CMO is %d.\n",ttt);
746: fprintf(stderr,"Available CMO tags in mathcap= %d elements : [ ",n);
747: for (i=0; i<n; i++) {
748: fprintf(stderr," %d ",cmo[i]);
749: }
750: fprintf(stderr," ] \n");
751: }
752: return(0);
753: }
754:
755: int cmoCheckMathCap(struct object obj, struct object *obp)
756: {
757: struct object mathcap;
758: struct object cmolist;
1.2 takayama 759: struct object mathcapMain;
1.4 takayama 760: struct object mathcapThird;
761: struct object ox;
762: struct object oxtag;
1.2 takayama 763: struct object ob0;
1.4 takayama 764: int oxsize;
1.1 maekawa 765: int n;
766: int i;
767: #define CMO_CHECK_MATH_CAP_LIST_SIZE 1024
768: int cmo[CMO_CHECK_MATH_CAP_LIST_SIZE];
769: if (obp == NULL) return(1);
1.2 takayama 770: /* printObject(*obp,0,stderr); for debug*/
1.1 maekawa 771: if (obp->tag != Sarray) {
772: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
773: printObject(*obp,0,stderr);
774: fprintf(stderr,"\n");
775: errorOxmisc2("cmoCheckMathCap: format error in the client->mathcapObjp field.\n");
776: }
777: mathcap = *obp;
1.2 takayama 778: /* Example of mathcap
779: [ $mathcap-object$ ,
780: [ [ 199909080 , $Ox_system=ox_sm1.plain$ , $Version=2.991106$ ,
781: $HOSTTYPE=i386$ ] ,
782: [ 262 , 263 , 264 , 265 , 266 , 268 , 269 , 272 , 273 , 275 ,
783: 276 ] ,
1.4 takayama 784: [ [ 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 785: */
786:
1.1 maekawa 787: n = getoaSize(mathcap);
788: if (n < 2) {
789: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
790: printObject(*obp,0,stderr);
791: fprintf(stderr,"\n");
792: errorOxmisc2("cmoCheckMathCap: length of mathcap is wrong in the client->mathcapObjp field.\n");
793: }
1.2 takayama 794: ob0 = getoa(mathcap,0);
795: if (ob0.tag != Sdollar) {
796: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
797: printObject(*obp,0,stderr);
798: fprintf(stderr,"\n");
799: errorOxmisc2("cmoCheckMathCap: The first field must be the string mathcap-object.\n");
800: }
801: if (strcmp(KopString(ob0),"mathcap-object") != 0) {
802: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
803: printObject(*obp,0,stderr);
804: fprintf(stderr,"\n");
805: errorOxmisc2("cmoCheckMathCap: The mathcap must be of the form [(mathcap-object) [...]]\n");
806: }
807:
1.1 maekawa 808: /* I should check
1.2 takayama 809: getoa(getoa(mathcap,1),2)
1.1 maekawa 810: contains OX_DATA.
811: It has not yet implemented.
812: */
1.2 takayama 813: mathcapMain = getoa(mathcap,1);
814: if (mathcapMain.tag != Sarray) {
815: fprintf(stderr,"cmoCheckMathCap: mathcap[1] is \n");
816: printObject(mathcapMain,0,stderr);
817: fprintf(stderr,"\n");
818: errorOxmisc2("cmoCheckMathCap: format error in the (client->mathcapObjp)[1] field. It should be an array.\n");
819: }
820: if (getoaSize(mathcapMain) < 3) {
821: fprintf(stderr,"cmoCheckMathCap: mathcap[1] is \n");
822: printObject(mathcapMain,0,stderr);
823: fprintf(stderr,"\n");
824: errorOxmisc2("cmoCheckMathCap: format error in the (client->mathcapObjp)[1] field. It should be an array of which length is more than 2.\n");
825: }
1.4 takayama 826: mathcapThird = getoa(mathcapMain,2);
827: oxsize = getoaSize(mathcapThird);
828: for (i=0; i<oxsize; i++) {
829: ox = getoa(mathcapThird,i);
830: if (ox.tag != Sarray) {
831: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
832: printObject(*obp,0,stderr);
833: fprintf(stderr,"\n");
834: errorOxmisc2("cmoCheckMathCap: the third element of mathcap is a list of lists.");
835: }
836: if (getoaSize(ox) != 0) {
837: oxtag = getoa(ox,0);
838: if (oxtag.tag != Sinteger) {
839: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
840: printObject(*obp,0,stderr);
841: fprintf(stderr,"\n");
842: errorOxmisc2("cmoCheckMathCap: the third element of mathcap must be [OX_DATA_xxx, [ ]].");
843: }
844: if (KopInteger(oxtag) == OX_DATA) {
845: if (getoaSize(ox) > 1) {
846: cmolist = getoa(ox,1);
847: if (cmolist.tag != Sarray) {
848: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
849: printObject(*obp,0,stderr);
850: fprintf(stderr,"\n");
851: errorOxmisc2("cmoCheckMathCap: mathcap[1] must be an array of integers.\n");
852: }
853: n = getoaSize(cmolist);
854: if (n > CMO_CHECK_MATH_CAP_LIST_SIZE) {
855: errorOxmisc2("cmoCheckMathCap: Too big cmo list.\n");
856: }
857: for (i=0; i<n; i++) {
858: cmo[i] = KopInteger(getoa(cmolist,i));
859: }
860: }else{
861: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
862: printObject(*obp,0,stderr);
863: fprintf(stderr,"\nox=");
864: printObject(ox,0,stderr);
865: errorOxmisc2("cmoCheckMathCap: [OX_DATA, cmolist]");
866: }
867: }
868: }
1.1 maekawa 869: }
870: return(cmoCheck00(obj,cmo,n));
871: }
872:
873:
874: struct object KoxGenPortFile(void) {
875: struct object ob;
876: ob = KpoString(oxGenPortFile());
877: return(ob);
878: }
879: void KoxRemovePortFile(void) {
880: oxRemovePortFile();
881: }
882:
883: void oxPushMathCap(struct mathCap *mathcap)
884: {
885: struct object rob;
886: rob = newMathCap(mathcap);
887: Kpush(rob);
888: }
889:
890: struct object KoxGenPass(void) {
891: struct object rob;
892: rob = KpoString(oxGenPass());
893: return(rob);
894: }
895:
896: struct object KoxGetPort(struct object host)
897: {
898: struct object rob;
899: int fdStream, fdControl;
900: int portStream, portControl;
901: extern int OpenedSocket;
902: char *sname;
903: rob = NullObject;
904: if (host.tag != Sdollar) {
905: errorOxmisc2("KoxGetPort: argument is not a string.");
906: return(rob);
907: }
908: sname = KopString(host);
909: fdControl = socketOpen(sname,0);
910: portControl = OpenedSocket;
911: fdStream = socketOpen(sname,0);
912: portStream = OpenedSocket;
913: rob = newObjectArray(4);
914: putoa(rob,0,KpoInteger(fdStream));
915: putoa(rob,1,KpoInteger(portStream));
916: putoa(rob,2,KpoInteger(fdControl));
917: putoa(rob,3,KpoInteger(portControl));
918: return(rob);
919: }
920:
921: struct object KoxCreateClient2(struct object peer,
922: struct object ipmask,
923: struct object pass)
924: {
925: struct object rob;
926: oxclientp client;
927: int fdStream, portStream, fdControl, portControl;
928: int i;
929: struct object ob1;
930: rob.tag = Snull;
931: if (peer.tag != Sarray) {
932: errorOxmisc2("KoxCreateClient2(): The first argument must be an array [fdStream, portStream, fdControl, portControl]");
933: return(rob);
934: }
935: if (getoaSize(peer) != 4) {
936: errorOxmisc2("KoxCreateClient2(): The first argument must be an array [fdStream, portStream, fdControl, portControl] of size 4.");
937: return(rob);
938: }
939: for (i=0; i<4; i++) {
940: ob1 = getoa(peer,i);
941: if (ob1.tag != Sinteger) {
942: errorOxmisc2("KoxCreateClient2(): The element of the first argument must be an integer.");
943: }
944: }
945: fdStream = KopInteger(getoa(peer,0));
946: portStream = KopInteger(getoa(peer,1));
947: fdControl = KopInteger(getoa(peer,2));
948: portControl = KopInteger(getoa(peer,3));
949:
950: if (ipmask.tag != Sinteger) {
951: errorOxmisc2("KoxCreateClient2(): ipmask must be an integer.");
952: }
953: if (pass.tag != Sdollar) {
954: errorOxmisc2("KoxCreateClient2(): pass must be a string.");
955: }
956:
957: client = oxCreateClient2(fdStream, portStream, fdControl, portControl,
958: KopInteger(ipmask), KopString(pass));
959: if (client == NULL) {
960: errorOxmisc2("KoxCreateClient2(): Open error.");
961: return(rob);
962: }
963: rob = newObjectArray(N_OF_CLIENT_FIELDS);
964: oxClientToObject(client,rob);
965: return(rob);
1.5 takayama 966: }
967:
968: int KgetCmoTagOfObject(struct object obj) {
969: int k;
970: k=cmoCheck00(obj,(int *)NULL,0);
971: return(k);
1.1 maekawa 972: }
973:
974: errorOxmisc2(char *s) {
1.6 takayama 975: SET_MYERROROUT;
1.1 maekawa 976: fprintf(MyErrorOut,"error in oxmisc2.c: %s\n",s);
977: errorKan1("%s\n"," ");
1.7 takayama 978: }
979:
980: struct object KoxPushCMD(struct object client,struct object cmd) {
981: int ans;
982: static oxclientp cc1 = NULL;
983: struct object rob;
984: rob.tag = Snull;
985: if (cc1 == NULL) {
986: cc1 = (oxclientp) mymalloc(sizeof(oxclient));
987: if (cc1 == NULL) {
988: errorOxmisc2("KoxReq(): no more memory.");
989: return(rob);
990: }
991: oxInitClient(cc1); /* BUG: is it fine? */
992: }
993:
994: if (oxObjectToClient(client,cc1) == -1) return(rob);
995: if (cc1 == NULL) {
996: errorOxmisc2("KoxReq(): the first argument must be a client object.");
997: return(rob);
998: }
999: if (cmd.tag != Sinteger) {
1000: errorOxmisc2("KoxReq(): the second argument must be an integer.");
1001: return(rob);
1002: }
1003: /* BUG: check the mathcap */
1004: oxSendOXheader(cc1->datafp2,OX_COMMAND,SerialOX++);
1005: oxSendInt32(cc1->datafp2,KopInteger(cmd));
1006: /* synchronize cc1 and client. */
1007: oxClientToObject(cc1,client);
1008: return(cmd);
1009: }
1010:
1011: struct object KoxPushCMO(struct object client,struct object ob) {
1012: int ans;
1013: static oxclientp cc1 = NULL;
1014: struct object rob;
1015: rob.tag = Snull;
1016: if (cc1 == NULL) {
1017: cc1 = (oxclientp) mymalloc(sizeof(oxclient));
1018: if (cc1 == NULL) {
1019: errorOxmisc2("KoxReq(): no more memory.");
1020: return(rob);
1021: }
1022: oxInitClient(cc1); /* BUG: is it fine? */
1023: }
1024:
1025: if (oxObjectToClient(client,cc1) == -1) return(rob);
1026: if (cc1 == NULL) {
1027: errorOxmisc2("KoxReq(): the first argument must be a client object.");
1028: return(rob);
1029: }
1030:
1031: /* request to the data channel */
1032: if (cc1->dstate != DSTATE_ANY) {
1033: errorOxmisc2("oxPushCMO: cc1->dstate != DSTATE_ANY, data channel is not ready to send data.\n");
1034: return(rob);
1035: }
1036:
1037: if (!cmoCheckMathCap(ob,(struct object *)cc1->mathcapObjp)) {
1038: errorOxmisc2("oxPushCMO: your peer does not understand this cmo.\n");
1039: return(rob);
1040: }
1041: oxSendOXheader(cc1->datafp2,OX_DATA,SerialOX++);
1042: cmoObjectToStream2(ob,cc1->datafp2);
1043: /* synchronize cc1 and client. */
1044: oxClientToObject(cc1,client);
1045: return(ob);
1.8 takayama 1046: }
1047:
1048: /* ------------- TODO ----------------- */
1049: oxclientp oxCreateControl_RFC_101(int fdstream,int portStream,
1050: int ipmask,char *pass);
1051: struct object KoxCreateControl_RFC_101(struct object peer,struct object ipmask,struct object pass)
1052: {
1053: struct object rob;
1054: oxclientp client;
1055: int fdStream, portStream;
1056: int i;
1057: struct object ob1;
1058: rob.tag = Snull;
1059: if (peer.tag != Sarray) {
1060: errorOxmisc2("KoxCreateControl_RFC_101(): The first argument must be an array [fdStream, portStream]");
1061: return(rob);
1062: }
1063: if (getoaSize(peer) != 2 ) {
1064: errorOxmisc2("KoxCreateControl_RFC_101(): The first argument must be an array [fdStream, portStream] of size 2.");
1065: return(rob);
1066: }
1067: for (i=0; i<getoaSize(peer); i++) {
1068: ob1 = getoa(peer,i);
1069: if (ob1.tag != Sinteger) {
1070: errorOxmisc2("KoxCreateControl_RFC_101(): The element of the first argument must be an integer.");
1071: }
1072: }
1073: fdStream = KopInteger(getoa(peer,0));
1074: portStream = KopInteger(getoa(peer,1));
1075:
1076: if (ipmask.tag != Sinteger) {
1077: errorOxmisc2("KoxCreateControl_RFC_101(): ipmask must be an integer.");
1078: }
1079: if (pass.tag != Sdollar) {
1080: errorOxmisc2("KoxCreateControl_RFC_101(): pass must be a string.");
1081: }
1082:
1083: client = oxCreateControl_RFC_101(fdStream, portStream,
1084: KopInteger(ipmask), KopString(pass));
1085: if (client == NULL) {
1086: errorOxmisc2("KoxCreateControl_RFC_101(): Open error.");
1087: return(rob);
1088: }
1089: rob = newObjectArray(N_OF_CLIENT_FIELDS);
1090: oxClientToObject(client,rob);
1091: return(rob);
1092: }
1093:
1094: oxclientp oxCreateControl_RFC_101(int fdstream,int portStream,
1095: int ipmask,char *pass)
1096: {
1097: static int clnum = 0;
1098: int v = 0;
1099: int fdControl = -1;
1100: int fdStream = -1;
1101: int m;
1102:
1103: char *s;
1104: oxclientp client;
1105: extern jmp_buf MyEnv_oxmisc ;
1106: int engineByteOrder;
1107: extern int Quiet;
1108:
1109: v = !Quiet;
1110:
1111: switch(ipmask) {
1112: case 0:/* only local */
1113: fdStream = socketAcceptLocal(fdstream);
1114: break;
1115: default:/* any */
1116: fdStream = socketAccept(fdstream);
1117: break;
1118: }
1119: if (v) fprintf(stderr,"\nControl port %d : Connected.\n",portStream);
1120:
1121: if (fdStream == -1 ) {
1122: fprintf(stderr,"\nOpen error in oxCreateControl_RFC_101.\n");
1123: return(NULL);
1124: }
1125:
1126: /* Authentication by password. */
1127: m = strlen(pass);
1128: s = (char *)mymalloc(sizeof(char)*(m+1));
1129: read(fdStream,s,m+1); s[m] = '\0';
1130: if (strcmp(s,pass) != 0) {
1131: fprintf(stderr,"oxCreateControl_RFC_101(): password authentication failed for control channel.\n");
1132: close(fdStream);
1133: return(NULL);
1134: }
1135:
1136:
1137: engineByteOrder = oxSetByteOrder(fdStream);
1138: if (v) fprintf(stderr,"Byte order for control stackmacine is %s.\n",
1139: (engineByteOrder == 0? "network byte order":
1140: (engineByteOrder == 1? "little indican":
1141: "big indian")));
1142:
1143:
1144: client = (oxclientp) mymalloc(sizeof(oxclient));
1145: oxInitClient(client);
1146: client->datafp2 = fp2open(fdStream);
1147: if (client->datafp2 == NULL) {
1148: fprintf(stderr,"oxCreateControl_RFC_101(): fp2open(fd) failed.\n");
1149: return(NULL);
1150: }
1151: client->dataport = portStream;
1152: client->controlport = -1;
1153: client->controlfd = -1;
1154: client->id = clnum; clnum++;
1155: client->type = CLIENT_SOCKET; /* socket */
1156: client->engineByteOrder = engineByteOrder;
1157: client->controlByteOrder = -1;
1158: return(client);
1.1 maekawa 1159: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>