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