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