Annotation of OpenXM/src/kan96xx/plugin/oxmisc2.c, Revision 1.24
1.24 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/plugin/oxmisc2.c,v 1.23 2004/09/17 07:27:28 takayama Exp $ */
1.1 maekawa 2: #include <stdio.h>
3: #include "ox_kan.h"
4: #include "oxmisc2.h" /* This file requires sm1 object description. */
5: #include "cmo.h"
1.8 takayama 6:
1.1 maekawa 7: extern FILE *MyErrorOut;
1.6 takayama 8: #define SET_MYERROROUT { if (MyErrorOut == NULL) MyErrorOut=stdout; }
9: /* It is also defined in oxmisc.c */
10:
1.1 maekawa 11: extern int SerialOX; /* defined in SerialOX */
12:
13: extern int OxVersion;
14:
15: int DebugMathCap = 1;
16:
17:
18:
19: int oxGet(oxclientp client, struct object *op,int *isObj)
1.12 takayama 20: /* This method should be synchronized. */
21: /* oxGet is a function for client. */
1.1 maekawa 22: {
23: int ans;
24: ox_stream os;
25: int m;
26: struct object rob;
27: int sss; /* Serial number of the recieved packet. */
28: *isObj = 0;
29: op->tag = Snull;
30: os = client->datafp2;
31: switch(client->dstate) {
32: case DSTATE_ANY:
33: m = oxGetOXheader(os,&sss);
34: switch(m) {
35: case OX_DATA:
36: client->dstate = DSTATE_WAIT_OX_DATA;
37: return(oxGet(client,op,isObj));
38: case OX_SYNC_BALL:
39: client->dstate = DSTATE_ANY;
40: return(OX_SYNC_BALL);
41: default:
42: errorOxmisc2("oxGet: cannot handle this tag.\n");
43: client->dstate = DSTATE_ERROR;
44: return(-1);
45: }
46: break;
47: case DSTATE_FIRST_SYNC: /* waiting the first sync ball */
48: /* I need to clear the buffer?? */
49: oxWaitSyncBall(os);
50: client->dstate = DSTATE_ANY;
51: oxSendSyncBall(os);
52: return(OX_SYNC_BALL);
53: break;
54: case DSTATE_WAIT_OX_DATA: /* waiting a cmo data. */
55: *op = cmoObjectFromStream2(client->datafp2);
56: client->dstate = DSTATE_ANY;
57: *isObj = 1;
58: return(0);
59: break;
60: case DSTATE_ERROR:
61: client->dstate = DSTATE_ERROR;
62: errorOxmisc2("oxGet: dstate == DSTATE_ERROR (error state)\n");
63: return(-1);
64: default:
65: client->dstate = DSTATE_ERROR;
66: errorOxmisc2("oxGet: Unknown state number.");
67: }
68:
69: return(-1);
70: }
71:
72: int oxGetFromControl(oxclientp client)
73: {
74: int ans = -1;
1.7 takayama 75: AbortIfRFC_101(client);
1.1 maekawa 76: if (client->cstate != -1) {
77: ans = oxGetResultOfControlInt32(client->controlfd);
78: if (ans != -1) { client->cstate = 0; }
79: else {client->cstate = -1; }
80: }
81: return(ans);
82: }
83:
84: int oxReq(oxclientp client,int func,struct object ob)
85: {
86: struct object *ob1p;
1.6 takayama 87: SET_MYERROROUT;
1.1 maekawa 88: /* request to the control channel */
89: if (func == SM_control_reset_connection ||
90: func == SM_control_kill) {
1.12 takayama 91: AbortIfRFC_101(client);
1.1 maekawa 92: switch(func) {
93: case SM_control_reset_connection:
94: oxReqControlResetConnection(client->controlfd);
1.9 takayama 95: client->cstate = 0;
1.1 maekawa 96: client->dstate = DSTATE_FIRST_SYNC;
97: break;
98: case SM_control_kill:
99: oxReqControlKill(client->controlfd);
100: client->cstate = 0;
101: client->dstate = DSTATE_ANY;
102: break;
103: }
104: fflush(NULL);
105: return(0);
106: }
107:
108: /* request to the data channel */
109: if (client->dstate != DSTATE_ANY) {
110: errorOxmisc2("oxReq: client->dstate != DSTATE_ANY, data channel is not ready to send data.\n");
111: return(-1);
112: }
113: switch(func) {
114: case SM_DUMMY_sendcmo:
115: if (!cmoCheckMathCap(ob,(struct object *)client->mathcapObjp)) {
116: errorOxmisc2("oxReq: your peer does not understand this cmo.\n");
117: return(-1);
118: }
119: oxSendOXheader(client->datafp2,OX_DATA,SerialOX++);
120: cmoObjectToStream2(ob,client->datafp2);
121: client->dstate = DSTATE_ANY;
122: break;
123: case SM_sync_ball:
124: oxSendSyncBall(client->datafp2);
125: client->dstate = DSTATE_ANY; /* We do not expect the sync ball.*/
126: client->cstate = 0; /* clear the cstate */
127: break;
128: case SM_popCMO:
129: oxReqPopCMO(client->datafp2);
130: client->dstate = DSTATE_ANY;
131: break;
132: case SM_mathcap:
133: oxReqMathCap(client->datafp2);
134: client->dstate = DSTATE_ANY;
135: break;
136: case SM_setMathCap:
137: /* ob = [(mathcap-obj) [[version num, system name] [sm tags]
1.12 takayama 138: ob1 smtags
139: oxtags [[ox numbers, [cmo numbers]]]
140: ob3 ob2 */
141: /* oxtags [[OX_DATA, [cmo numbers]],[OX_DATA_LOCAL,[opt]],...]*/
1.1 maekawa 142: {
143: struct object ob1;
144: struct object ob2;
145: struct object ob3;
1.4 takayama 146: struct object obm;
1.1 maekawa 147: struct object smtags;
1.4 takayama 148: struct object oxtags;
149: struct object ox;
1.12 takayama 150: int n,i;
151: struct mathCap mathcap;
1.1 maekawa 152:
1.12 takayama 153: if (strcmp(KopString(getoa(ob,0)),"mathcap-object") != 0) {
154: errorOxmisc2("data format error in oxReqSetMathCap");
155: client->dstate = DSTATE_ANY;
156: break;
157: }
1.4 takayama 158: obm = getoa(ob,1);
159: ob1 = getoa(obm,0);
160: smtags = getoa(obm,1);
161: oxtags = getoa(obm,2);
162: if (smtags.tag != Sarray || oxtags.tag != Sarray) {
1.12 takayama 163: errorOxmisc2("data format error in oxReqSetMathCap");
1.4 takayama 164: }
1.1 maekawa 165: ob1p = (struct object *) sGC_malloc(sizeof(struct object));
166: *ob1p = ob1;
167: mathcap.infop = ob1p;
1.4 takayama 168:
169: n = getoaSize(oxtags);
1.1 maekawa 170: if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
171: mathcap.oxSize = n;
172: for (i=0; i<n; i++) {
1.12 takayama 173: ox = getoa(oxtags,i);
174: if (ox.tag != Sarray) {
175: errorOxmisc2("Data format error of the third argument of mathcap.");
176: }
177: mathcap.ox[i] = KopInteger(getoa(ox,0));
178: if (mathcap.ox[i] == OX_DATA) {
179: if (getoaSize(ox) < 2) {
180: errorOxmisc2("Data format error in an entry of the third argument of mathcap.");
181: }
182: ob2 = getoa(ox,1);
183: if (ob2.tag != Sarray) {
184: errorOxmisc2("Data format error in an entry of the third argument of mathcap.");
185: }
186: mathcap.n = getoaSize(ob2);
187: if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
188: for (i=0; i<mathcap.n; i++) {
189: mathcap.cmo[i] = KopInteger(getoa(ob2,i));
190: }
191: }
1.1 maekawa 192: }
193:
194: n = getoaSize(smtags);
195: if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
196: mathcap.smSize = n;
197: for (i=0; i<n; i++) {
1.12 takayama 198: mathcap.sm[i] = KopInteger(getoa(smtags,i));
1.1 maekawa 199: }
200:
201: oxReqSetMathCap(client->datafp2,&mathcap);
202: client->dstate = DSTATE_ANY;
203: }
204: break;
205: case SM_pops:
206: if (ob.tag != Sinteger) {
207: errorOxmisc2("SM_pops : the argument must be an integer.");
208: return(-1);
209: }
210: oxReqPops(client->datafp2, KopInteger(ob));
211: client->dstate = DSTATE_ANY;
212: break;
213: case SM_executeStringByLocalParser:
214: if (ob.tag != Sdollar) {
215: errorOxmisc2("SM_executeStringByLocalParser : the argument must be a string.");
216: return(-1);
217: }
218: oxReqExecuteStringByLocalParser(client->datafp2,KopString(ob));
219: client->dstate = DSTATE_ANY;
220: break;
221: case SM_executeFunction:
222: if (ob.tag != Sdollar) {
223: errorOxmisc2("SM_executeFunction : the argument must be a string.");
224: return(-1);
225: }
226: oxReqExecuteFunction(client->datafp2,KopString(ob));
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: {
282: struct object rob;
283: oxclientp client;
1.24 ! takayama 284: char *passControl; char *passData;
! 285: struct object tob;
! 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: {
369: struct object rob;
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: {
385: struct object ob;
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: {
424: struct object ob1;
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;
489: struct object rob;
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;
520: struct object rob;
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;
551: struct object rob;
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;
581: struct object rob;
582: int i;
583: int tt;
584: struct object ob1;
585: struct object ob2;
586: struct object ob0;
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;
651: struct object rob;
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;
688: struct object rob;
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;
723: struct object rob;
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;
745: struct object rob;
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: {
854: struct object mathcap;
855: struct object cmolist;
1.2 takayama 856: struct object mathcapMain;
1.4 takayama 857: struct object mathcapThird;
858: struct object ox;
859: struct object oxtag;
1.2 takayama 860: struct object ob0;
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) {
972: struct object ob;
973: ob = KpoString(oxGenPortFile());
974: return(ob);
975: }
976: void KoxRemovePortFile(void) {
977: oxRemovePortFile();
978: }
979:
980: void oxPushMathCap(struct mathCap *mathcap)
981: {
982: struct object rob;
983: rob = newMathCap(mathcap);
984: Kpush(rob);
985: }
986:
987: struct object KoxGenPass(void) {
988: struct object rob;
989: rob = KpoString(oxGenPass());
990: return(rob);
991: }
992:
993: struct object KoxGetPort(struct object host)
994: {
995: struct object rob;
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: {
1019: struct object rob;
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: {
1042: struct object rob;
1043: oxclientp client;
1044: int fdStream, portStream, fdControl, portControl;
1045: int i;
1046: struct object ob1;
1.23 takayama 1047: struct object opassControl, opassData;
1.1 maekawa 1048: rob.tag = Snull;
1049: if (peer.tag != Sarray) {
1050: errorOxmisc2("KoxCreateClient2(): The first argument must be an array [fdStream, portStream, fdControl, portControl]");
1051: return(rob);
1052: }
1053: if (getoaSize(peer) != 4) {
1054: errorOxmisc2("KoxCreateClient2(): The first argument must be an array [fdStream, portStream, fdControl, portControl] of size 4.");
1055: return(rob);
1056: }
1057: for (i=0; i<4; i++) {
1058: ob1 = getoa(peer,i);
1059: if (ob1.tag != Sinteger) {
1060: errorOxmisc2("KoxCreateClient2(): The element of the first argument must be an integer.");
1061: }
1062: }
1063: fdStream = KopInteger(getoa(peer,0));
1064: portStream = KopInteger(getoa(peer,1));
1065: fdControl = KopInteger(getoa(peer,2));
1066: portControl = KopInteger(getoa(peer,3));
1067:
1068: if (ipmask.tag != Sinteger) {
1069: errorOxmisc2("KoxCreateClient2(): ipmask must be an integer.");
1070: }
1.23 takayama 1071: if (pass.tag == Sdollar) {
1072: opassControl = pass; opassData = pass;
1073: }else if (pass.tag == Sarray) {
1074: if (getoaSize(pass) < 2) errorOxmisc2("KoxCreateClient2: #passArray < 2.");
1075: opassControl = getoa(pass,0);
1076: opassData = getoa(pass,1);
1077: }else{
1078: errorOxmisc2("KoxCreateClient2(): pass must be a string or an array.");
1079: }
1080: if ((opassControl.tag != Sdollar) || (opassData.tag != Sdollar)) {
1081: errorOxmisc2("KoxCreateClient2(): opassControl or opassData must be a string.");
1.1 maekawa 1082: }
1083:
1084: client = oxCreateClient2(fdStream, portStream, fdControl, portControl,
1.23 takayama 1085: KopInteger(ipmask),
1086: KopString(opassControl),KopString(opassData));
1.1 maekawa 1087: if (client == NULL) {
1088: errorOxmisc2("KoxCreateClient2(): Open error.");
1089: return(rob);
1090: }
1091: rob = newObjectArray(N_OF_CLIENT_FIELDS);
1092: oxClientToObject(client,rob);
1.14 takayama 1093: oxClientListUpdate(rob);
1.1 maekawa 1094: return(rob);
1.5 takayama 1095: }
1096:
1097: int KgetCmoTagOfObject(struct object obj) {
1098: int k;
1099: k=cmoCheck00(obj,(int *)NULL,0);
1100: return(k);
1.1 maekawa 1101: }
1102:
1103: errorOxmisc2(char *s) {
1.6 takayama 1104: SET_MYERROROUT;
1.1 maekawa 1105: fprintf(MyErrorOut,"error in oxmisc2.c: %s\n",s);
1106: errorKan1("%s\n"," ");
1.7 takayama 1107: }
1108:
1109: struct object KoxPushCMD(struct object client,struct object cmd) {
1110: int ans;
1111: static oxclientp cc1 = NULL;
1112: struct object rob;
1113: rob.tag = Snull;
1114: if (cc1 == NULL) {
1115: cc1 = (oxclientp) mymalloc(sizeof(oxclient));
1116: if (cc1 == NULL) {
1117: errorOxmisc2("KoxReq(): no more memory.");
1118: return(rob);
1119: }
1120: oxInitClient(cc1); /* BUG: is it fine? */
1121: }
1122:
1123: if (oxObjectToClient(client,cc1) == -1) return(rob);
1124: if (cc1 == NULL) {
1125: errorOxmisc2("KoxReq(): the first argument must be a client object.");
1126: return(rob);
1127: }
1128: if (cmd.tag != Sinteger) {
1129: errorOxmisc2("KoxReq(): the second argument must be an integer.");
1130: return(rob);
1131: }
1132: /* BUG: check the mathcap */
1133: oxSendOXheader(cc1->datafp2,OX_COMMAND,SerialOX++);
1134: oxSendInt32(cc1->datafp2,KopInteger(cmd));
1135: /* synchronize cc1 and client. */
1136: oxClientToObject(cc1,client);
1137: return(cmd);
1138: }
1139:
1140: struct object KoxPushCMO(struct object client,struct object ob) {
1141: int ans;
1142: static oxclientp cc1 = NULL;
1143: struct object rob;
1144: rob.tag = Snull;
1145: if (cc1 == NULL) {
1146: cc1 = (oxclientp) mymalloc(sizeof(oxclient));
1147: if (cc1 == NULL) {
1148: errorOxmisc2("KoxReq(): no more memory.");
1149: return(rob);
1150: }
1151: oxInitClient(cc1); /* BUG: is it fine? */
1152: }
1153:
1154: if (oxObjectToClient(client,cc1) == -1) return(rob);
1155: if (cc1 == NULL) {
1156: errorOxmisc2("KoxReq(): the first argument must be a client object.");
1157: return(rob);
1158: }
1159:
1160: /* request to the data channel */
1161: if (cc1->dstate != DSTATE_ANY) {
1162: errorOxmisc2("oxPushCMO: cc1->dstate != DSTATE_ANY, data channel is not ready to send data.\n");
1163: return(rob);
1164: }
1165:
1166: if (!cmoCheckMathCap(ob,(struct object *)cc1->mathcapObjp)) {
1.12 takayama 1167: errorOxmisc2("oxPushCMO: your peer does not understand this cmo.\n");
1168: return(rob);
1.7 takayama 1169: }
1170: oxSendOXheader(cc1->datafp2,OX_DATA,SerialOX++);
1171: cmoObjectToStream2(ob,cc1->datafp2);
1172: /* synchronize cc1 and client. */
1173: oxClientToObject(cc1,client);
1174: return(ob);
1.8 takayama 1175: }
1176:
1177: oxclientp oxCreateControl_RFC_101(int fdstream,int portStream,
1.12 takayama 1178: int ipmask,char *pass);
1.8 takayama 1179: struct object KoxCreateControl_RFC_101(struct object peer,struct object ipmask,struct object pass)
1180: {
1181: struct object rob;
1182: oxclientp client;
1183: int fdStream, portStream;
1184: int i;
1185: struct object ob1;
1186: rob.tag = Snull;
1187: if (peer.tag != Sarray) {
1188: errorOxmisc2("KoxCreateControl_RFC_101(): The first argument must be an array [fdStream, portStream]");
1189: return(rob);
1190: }
1191: if (getoaSize(peer) != 2 ) {
1192: errorOxmisc2("KoxCreateControl_RFC_101(): The first argument must be an array [fdStream, portStream] of size 2.");
1193: return(rob);
1194: }
1195: for (i=0; i<getoaSize(peer); i++) {
1196: ob1 = getoa(peer,i);
1197: if (ob1.tag != Sinteger) {
1198: errorOxmisc2("KoxCreateControl_RFC_101(): The element of the first argument must be an integer.");
1199: }
1200: }
1201: fdStream = KopInteger(getoa(peer,0));
1202: portStream = KopInteger(getoa(peer,1));
1203:
1204: if (ipmask.tag != Sinteger) {
1205: errorOxmisc2("KoxCreateControl_RFC_101(): ipmask must be an integer.");
1206: }
1207: if (pass.tag != Sdollar) {
1208: errorOxmisc2("KoxCreateControl_RFC_101(): pass must be a string.");
1209: }
1210:
1211: client = oxCreateControl_RFC_101(fdStream, portStream,
1.12 takayama 1212: KopInteger(ipmask), KopString(pass));
1.8 takayama 1213: if (client == NULL) {
1214: errorOxmisc2("KoxCreateControl_RFC_101(): Open error.");
1215: return(rob);
1216: }
1217: rob = newObjectArray(N_OF_CLIENT_FIELDS);
1218: oxClientToObject(client,rob);
1219: return(rob);
1220: }
1221:
1222: oxclientp oxCreateControl_RFC_101(int fdstream,int portStream,
1.12 takayama 1223: int ipmask,char *pass)
1.8 takayama 1224: {
1225: int v = 0;
1226: int fdControl = -1;
1227: int fdStream = -1;
1228: int m;
1229:
1230: char *s;
1231: oxclientp client;
1.13 takayama 1232: #if defined(__CYGWIN__)
1233: extern sigjmp_buf MyEnv_oxmisc;
1234: #else
1235: extern jmp_buf MyEnv_oxmisc;
1236: #endif
1.8 takayama 1237: int engineByteOrder;
1238: extern int Quiet;
1239:
1240: v = !Quiet;
1241:
1242: switch(ipmask) {
1243: case 0:/* only local */
1244: fdStream = socketAcceptLocal(fdstream);
1245: break;
1246: default:/* any */
1247: fdStream = socketAccept(fdstream);
1248: break;
1249: }
1250: if (v) fprintf(stderr,"\nControl port %d : Connected.\n",portStream);
1251:
1252: if (fdStream == -1 ) {
1253: fprintf(stderr,"\nOpen error in oxCreateControl_RFC_101.\n");
1254: return(NULL);
1255: }
1256:
1257: /* Authentication by password. */
1258: m = strlen(pass);
1259: s = (char *)mymalloc(sizeof(char)*(m+1));
1260: read(fdStream,s,m+1); s[m] = '\0';
1261: if (strcmp(s,pass) != 0) {
1262: fprintf(stderr,"oxCreateControl_RFC_101(): password authentication failed for control channel.\n");
1263: close(fdStream);
1264: return(NULL);
1265: }
1266:
1267:
1268: engineByteOrder = oxSetByteOrder(fdStream);
1269: if (v) fprintf(stderr,"Byte order for control stackmacine is %s.\n",
1.12 takayama 1270: (engineByteOrder == 0? "network byte order":
1271: (engineByteOrder == 1? "little indican":
1272: "big indian")));
1.8 takayama 1273:
1274:
1275: client = (oxclientp) mymalloc(sizeof(oxclient));
1276: oxInitClient(client);
1277: client->datafp2 = fp2open(fdStream);
1278: if (client->datafp2 == NULL) {
1279: fprintf(stderr,"oxCreateControl_RFC_101(): fp2open(fd) failed.\n");
1280: return(NULL);
1281: }
1282: client->dataport = portStream;
1283: client->controlport = -1;
1284: client->controlfd = -1;
1.14 takayama 1285: client->id = oxGetClientID();
1.11 takayama 1286: client->type = CLIENT_SOCKET; /* socket */
1287: client->engineByteOrder = engineByteOrder;
1288: client->controlByteOrder = -1;
1289: return(client);
1290: }
1291:
1292: oxclientp oxCreateEngine_RFC_101(int fdstream,int portStream,
1.12 takayama 1293: int ipmask,char *pass, int engineID);
1.11 takayama 1294: struct object KoxCreateEngine_RFC_101(struct object peer,struct object ipmask,struct object pass, struct object engineID)
1295: {
1296: struct object rob;
1297: oxclientp client;
1298: int fdStream, portStream;
1299: int i;
1300: struct object ob1;
1301: rob.tag = Snull;
1302: if (peer.tag != Sarray) {
1303: errorOxmisc2("KoxCreateEngine_RFC_101(): The first argument must be an array [fdStream, portStream]");
1304: return(rob);
1305: }
1306: if (getoaSize(peer) != 2 ) {
1307: errorOxmisc2("KoxCreateEngine_RFC_101(): The first argument must be an array [fdStream, portStream] of size 2.");
1308: return(rob);
1309: }
1310: for (i=0; i<getoaSize(peer); i++) {
1311: ob1 = getoa(peer,i);
1312: if (ob1.tag != Sinteger) {
1313: errorOxmisc2("KoxCreateEngine_RFC_101(): The element of the first argument must be an integer.");
1314: }
1315: }
1316: fdStream = KopInteger(getoa(peer,0));
1317: portStream = KopInteger(getoa(peer,1));
1318:
1319: if (ipmask.tag != Sinteger) {
1320: errorOxmisc2("KoxCreateEngine_RFC_101(): ipmask must be an integer.");
1321: }
1322: if (pass.tag != Sdollar) {
1323: errorOxmisc2("KoxCreateEngine_RFC_101(): pass must be a string.");
1324: }
1325: if (engineID.tag != Sinteger) {
1326: errorOxmisc2("KoxCreateEngine_RFC_101(): engineID must be an integer.");
1327: }
1328:
1329: client = oxCreateEngine_RFC_101(fdStream, portStream,
1.12 takayama 1330: KopInteger(ipmask), KopString(pass),KopInteger(engineID));
1.11 takayama 1331: if (client == NULL) {
1332: errorOxmisc2("KoxCreateEngine_RFC_101(): Open error.");
1333: return(rob);
1334: }
1335: rob = newObjectArray(N_OF_CLIENT_FIELDS);
1336: oxClientToObject(client,rob);
1.14 takayama 1337: oxClientListUpdate(rob);
1.11 takayama 1338: return(rob);
1339: }
1340:
1341: oxclientp oxCreateEngine_RFC_101(int fdstream,int portStream,
1.12 takayama 1342: int ipmask,char *pass,int engineID)
1.11 takayama 1343: {
1344: int v = 0;
1345: int fdControl = -1;
1346: int fdStream = -1;
1347: int m;
1348:
1349: char *s;
1350: oxclientp client;
1.13 takayama 1351: #if defined(__CYGWIN__)
1352: extern sigjmp_buf MyEnv_oxmisc;
1353: #else
1354: extern jmp_buf MyEnv_oxmisc;
1355: #endif
1.11 takayama 1356: int engineByteOrder;
1357: extern int Quiet;
1358:
1359: v = !Quiet;
1360:
1361: switch(ipmask) {
1362: case 0:/* only local */
1363: fdStream = socketAcceptLocal(fdstream);
1364: break;
1365: default:/* any */
1366: fdStream = socketAccept(fdstream);
1367: break;
1368: }
1369: if (v) fprintf(stderr,"\nEngine port %d : Connected.\n",portStream);
1370:
1371: if (fdStream == -1 ) {
1372: fprintf(stderr,"\nOpen error in oxCreateEngine_RFC_101.\n");
1373: return(NULL);
1374: }
1375:
1376: /* Authentication by password. */
1377: /* skip password check for now. BUG.
1.12 takayama 1378: m = strlen(pass);
1379: s = (char *)mymalloc(sizeof(char)*(m+1));
1380: read(fdStream,s,m+1); s[m] = '\0';
1381: if (strcmp(s,pass) != 0) {
1382: fprintf(stderr,"oxCreateEngine_RFC_101(): password authentication failed for control channel.\n");
1383: close(fdStream);
1384: return(NULL);
1385: }
1.11 takayama 1386: */
1387:
1388: engineByteOrder = oxSetByteOrder(fdStream);
1389: if (v) fprintf(stderr,"Byte order for engine stackmacine is %s.\n",
1.12 takayama 1390: (engineByteOrder == 0? "network byte order":
1391: (engineByteOrder == 1? "little indican":
1392: "big indian")));
1.11 takayama 1393:
1394:
1395: client = (oxclientp) mymalloc(sizeof(oxclient));
1396: oxInitClient(client);
1397: client->datafp2 = fp2open(fdStream);
1398: if (client->datafp2 == NULL) {
1399: fprintf(stderr,"oxCreateEngine_RFC_101(): fp2open(fd) failed.\n");
1400: return(NULL);
1401: }
1402: client->dataport = portStream;
1403: client->controlport = -1;
1404: client->controlfd = -1;
1.16 takayama 1405: client->id = oxGetClientID();
1406: client->engineID = engineID;
1.8 takayama 1407: client->type = CLIENT_SOCKET; /* socket */
1408: client->engineByteOrder = engineByteOrder;
1409: client->controlByteOrder = -1;
1410: return(client);
1.1 maekawa 1411: }
1.14 takayama 1412:
1413: void oxClientListUpdate(struct object ob) {
1414: int id;
1415: extern struct object OxClientList[];
1416: id = KopInteger(getoa(ob,8));
1417: /* printf("id=%d\n",id); */
1418: if ((id <MAX_N_OF_CLIENT) && (id >= 0)) {
1419: OxClientList[id] = ob;
1420: }else{
1421: errorOxmisc2("oxClientListUpdate(): the client table is full.\n");
1422: }
1423: }
1424: void oxClientListRemove(struct object ob) {
1425: int id;
1426: extern struct object OxClientList[];
1427: id = KopInteger(getoa(ob,8));
1428: if ((id <MAX_N_OF_CLIENT) && (id >= 0)) {
1429: (OxClientList[id]).tag = Snull;
1430: }else{
1431: /* errorOxmisc2("oxClientListRemove(): the client table is full.\n");*/
1432: }
1433: }
1.17 takayama 1434: static void KoxCleanClientList() {
1435: extern int OxClientListn;
1436: extern struct object OxClientList[];
1437: int i,j,n;
1438: struct object ob;
1439: n = 0;
1440: for (i=0; i<OxClientListn; i++) {
1441: if ((OxClientList[i]).tag != Snull) {
1442: if (!isItClientObject(OxClientList[i])) {
1443: (OxClientList[i]).tag = Snull;
1444: }
1445: }
1446: }
1447: }
1.14 takayama 1448: struct object KoxGetClientList() {
1449: extern int OxClientListn;
1450: extern struct object OxClientList[];
1451: int i,j,n;
1452: struct object rob;
1.17 takayama 1453: KoxCleanClientList();
1.14 takayama 1454: n = 0;
1455: for (i=0; i<OxClientListn; i++) {
1456: if ((OxClientList[i]).tag != Snull) n++;
1457: }
1458: rob = newObjectArray(n);
1459: for (i=0, j=0; i<OxClientListn; i++) {
1460: if ((OxClientList[i]).tag != Snull) {
1461: if (j >= n) {
1462: j=0;
1463: errorOxmisc2("oxGetClientList(): the client table is broken.\n");
1464: }
1465: putoa(rob,j,OxClientList[i]);
1466: j++;
1467: }
1468: }
1469: return rob;
1470: }
1471:
1472:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>