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