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