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