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