/* $OpenXM: OpenXM/src/kan96xx/plugin/oxmisc2.c,v 1.28 2020/10/06 11:33:47 takayama Exp $ */ #include #include #include #include "ox_kan.h" #include "oxmisc2.h" /* This file requires sm1 object description. */ #include "cmo.h" extern FILE *MyErrorOut; #define SET_MYERROROUT { if (MyErrorOut == NULL) MyErrorOut=stdout; } /* It is also defined in oxmisc.c */ extern int SerialOX; /* defined in SerialOX */ extern int OxVersion; int DebugMathCap = 1; int oxGet(oxclientp client, struct object *op,int *isObj) /* This method should be synchronized. */ /* oxGet is a function for client. */ { int ans; ox_stream os; int m; struct object rob = OINIT; int sss; /* Serial number of the recieved packet. */ *isObj = 0; op->tag = Snull; os = client->datafp2; switch(client->dstate) { case DSTATE_ANY: m = oxGetOXheader(os,&sss); switch(m) { case OX_DATA: client->dstate = DSTATE_WAIT_OX_DATA; return(oxGet(client,op,isObj)); case OX_SYNC_BALL: client->dstate = DSTATE_ANY; return(OX_SYNC_BALL); default: errorOxmisc2("oxGet: cannot handle this tag.\n"); client->dstate = DSTATE_ERROR; return(-1); } break; case DSTATE_FIRST_SYNC: /* waiting the first sync ball */ /* I need to clear the buffer?? */ oxWaitSyncBall(os); client->dstate = DSTATE_ANY; oxSendSyncBall(os); return(OX_SYNC_BALL); break; case DSTATE_WAIT_OX_DATA: /* waiting a cmo data. */ *op = cmoObjectFromStream2(client->datafp2); client->dstate = DSTATE_ANY; *isObj = 1; return(0); break; case DSTATE_ERROR: client->dstate = DSTATE_ERROR; errorOxmisc2("oxGet: dstate == DSTATE_ERROR (error state)\n"); return(-1); default: client->dstate = DSTATE_ERROR; errorOxmisc2("oxGet: Unknown state number."); } return(-1); } int oxGetFromControl(oxclientp client) { int ans = -1; AbortIfRFC_101(client); if (client->cstate != -1) { ans = oxGetResultOfControlInt32(client->controlfd); if (ans != -1) { client->cstate = 0; } else {client->cstate = -1; } } return(ans); } int oxReq(oxclientp client,int func,struct object ob) { struct object *ob1p; SET_MYERROROUT; /* request to the control channel */ if (func == SM_control_reset_connection || func == SM_control_kill) { AbortIfRFC_101(client); switch(func) { case SM_control_reset_connection: oxReqControlResetConnection(client->controlfd); client->cstate = 0; client->dstate = DSTATE_FIRST_SYNC; break; case SM_control_kill: oxReqControlKill(client->controlfd); client->cstate = 0; client->dstate = DSTATE_ANY; break; } fflush(NULL); return(0); } /* request to the data channel */ if (client->dstate != DSTATE_ANY) { errorOxmisc2("oxReq: client->dstate != DSTATE_ANY, data channel is not ready to send data.\n"); return(-1); } switch(func) { case SM_DUMMY_sendcmo: if (!cmoCheckMathCap(ob,(struct object *)client->mathcapObjp)) { errorOxmisc2("oxReq: your peer does not understand this cmo.\n"); return(-1); } oxSendOXheader(client->datafp2,OX_DATA,SerialOX++); cmoObjectToStream2(ob,client->datafp2); client->dstate = DSTATE_ANY; break; case SM_sync_ball: oxSendSyncBall(client->datafp2); client->dstate = DSTATE_ANY; /* We do not expect the sync ball.*/ client->cstate = 0; /* clear the cstate */ break; case SM_popCMO: oxReqPopCMO(client->datafp2); client->dstate = DSTATE_ANY; break; case SM_mathcap: oxReqMathCap(client->datafp2); client->dstate = DSTATE_ANY; break; case SM_setMathCap: /* ob = [(mathcap-obj) [[version num, system name] [sm tags] ob1 smtags oxtags [[ox numbers, [cmo numbers]]] ob3 ob2 */ /* oxtags [[OX_DATA, [cmo numbers]],[OX_DATA_LOCAL,[opt]],...]*/ { struct object ob1 = OINIT; struct object ob2 = OINIT; struct object ob3 = OINIT; struct object obm = OINIT; struct object smtags = OINIT; struct object oxtags = OINIT; struct object ox = OINIT; int n,i; struct mathCap mathcap; if (strcmp(KopString(getoa(ob,0)),"mathcap-object") != 0) { errorOxmisc2("data format error in oxReqSetMathCap"); client->dstate = DSTATE_ANY; break; } obm = getoa(ob,1); ob1 = getoa(obm,0); smtags = getoa(obm,1); oxtags = getoa(obm,2); if (smtags.tag != Sarray || oxtags.tag != Sarray) { errorOxmisc2("data format error in oxReqSetMathCap"); } ob1p = (struct object *) sGC_malloc(sizeof(struct object)); *ob1p = ob1; mathcap.infop = ob1p; n = getoaSize(oxtags); if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer."); mathcap.oxSize = n; for (i=0; i= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer."); for (i=0; i= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer."); mathcap.smSize = n; for (i=0; idatafp2,&mathcap); client->dstate = DSTATE_ANY; } break; case SM_pops: if (ob.tag != Sinteger) { errorOxmisc2("SM_pops : the argument must be an integer."); return(-1); } oxReqPops(client->datafp2, KopInteger(ob)); client->dstate = DSTATE_ANY; break; case SM_executeStringByLocalParser: if (ob.tag != Sdollar) { errorOxmisc2("SM_executeStringByLocalParser : the argument must be a string."); return(-1); } oxReqExecuteStringByLocalParser(client->datafp2,KopString(ob)); client->dstate = DSTATE_ANY; break; case SM_executeFunction: if (ob.tag != Sdollar) { errorOxmisc2("SM_executeFunction : the argument must be a string."); return(-1); } oxReqExecuteFunction(client->datafp2,KopString(ob)); client->dstate = DSTATE_ANY; break; case SM_executeFunctionWithOptionalArgument: if (ob.tag != Sdollar) { errorOxmisc2("SM_executeFunctionWithOptionalArgument : the argument must be a string."); return(-1); } oxReqExecuteFunctionWithOptionalArgument(client->datafp2,KopString(ob)); client->dstate = DSTATE_ANY; break; case SM_popString: oxReqPopString(client->datafp2); client->dstate = DSTATE_ANY; break; case SM_evalName: if (ob.tag != Sdollar) { errorOxmisc2("SM_evalName : the argument must be a string."); return(-1); } oxReqEvalName(client->datafp2,KopString(ob)); client->dstate = DSTATE_ANY; break; case SM_setName: if (ob.tag != Sdollar) { errorOxmisc2("SM_setName : the argument must be a string."); return(-1); } oxReqSetName(client->datafp2,KopString(ob)); client->dstate = DSTATE_ANY; break; case SM_getsp: oxReqSingleOperand(client->datafp2,SM_getsp); client->dstate = DSTATE_ANY; break; case SM_dupErrors: oxReqSingleOperand(client->datafp2,SM_dupErrors); client->dstate = DSTATE_ANY; break; case SM_pushCMOtag: oxReqSingleOperand(client->datafp2,SM_pushCMOtag); client->dstate = DSTATE_ANY; break; default: fprintf(MyErrorOut,"func=%d ",func); errorOxmisc2("This function is not implemented."); break; } fp2fflush(client->datafp2); return(0); } struct object KoxCreateClient(struct object ip, struct object portStream, struct object portControl,struct object pass) { struct object rob = OINIT; oxclientp client; char *passControl; char *passData; struct object tob = OINIT; passControl = NULL; passData = NULL; rob.tag = Snull; if (ip.tag != Sdollar) { errorOxmisc2("KoxCreateClient(): The first argument must be a hostname given by a string."); return(rob); } if (portStream.tag == Sdollar) { client = oxCreateClientFile(KopString(ip),KopString(portStream), "/dev/null","w"); if (client == NULL) { errorOxmisc2("KoxCreateClient(): Open error."); return(rob); } rob = newObjectArray(N_OF_CLIENT_FIELDS); oxClientToObject(client,rob); return(rob); } if (portStream.tag != Sinteger) { errorOxmisc2("KoxCreateClient(): The second argument must be a port number given in an integer."); return(rob); } if (portControl.tag != Sinteger) { errorOxmisc2("KoxCreateClient(): The third argument must be a port number given in an integer."); return(rob); } if (pass.tag == Sarray) { if (getoaSize(pass) < 2) { errorOxmisc2("KoxCreateClient(): the fourth argument --- pass must be an array of strings."); return rob; } tob = getoa(pass,0); if (tob.tag != Sdollar) { errorOxmisc2("KoxCreateClient(): the fourth argument --- pass must be an array of strings."); return rob; } passControl = KopString(tob); tob = getoa(pass,1); if (tob.tag != Sdollar) { errorOxmisc2("KoxCreateClient(): the fourth argument --- pass must be an array of strings."); return rob; } passData = KopString(tob); } client = oxCreateClient(KopString(ip),KopInteger(portStream),KopInteger(portControl),passControl,passData); if (client == NULL) { errorOxmisc2("KoxCreateClient(): Open error."); return(rob); } rob = newObjectArray(N_OF_CLIENT_FIELDS); oxClientToObject(client,rob); oxClientListUpdate(rob); return(rob); } static int isItClientObject(struct object ob) { int size,i; struct object ee[N_OF_CLIENT_FIELDS]; if (ob.tag != Sarray) { return(0); } size = getoaSize(ob); if (size != N_OF_CLIENT_FIELDS) return(0); for (i=0; idatafp2); putoa(rob,1,ob); putoa(rob,2,KpoInteger(client->dataport)); putoa(rob,3,KpoInteger(client->controlfd)); putoa(rob,4,KpoInteger(client->controlport)); putoa(rob,5,KpoInteger(client->dstate)); putoa(rob,6,KpoInteger(client->cstate)); putoa(rob,7,KpoInteger(client->humanio)); putoa(rob,8,KpoInteger(client->id)); putoa(rob,9,KpoInteger(client->type)); if (client->mathcapObjp == NULL) { putoa(rob,10,NullObject); }else{ putoa(rob,10,*((struct object *)(client->mathcapObjp))); } putoa(rob,11,KpoInteger(client->engineByteOrder)); putoa(rob,12,KpoInteger(client->controlByteOrder)); putoa(rob,13,KpoInteger(client->engineID)); return(0); } int oxObjectToClient(struct object ob,oxclientp cp) { struct object ob1 = OINIT; struct object *obp; if (cp == NULL) { errorOxmisc2("oxObjectToClient(): the second argument is NULL"); return(-1); } if (!isItClientObject(ob)) { errorOxmisc2("oxObjectToClient(): the first argument is not client object."); oxInitClient(cp); return(-1); } ob1 = getoa(ob,1); cp->datafp2 = (FILE2 *) (ob1.rc.voidp); ob1 = getoa(ob,2); cp->dataport = KopInteger(ob1); ob1 = getoa(ob,3); cp->controlfd = KopInteger(ob1); ob1 = getoa(ob,4); cp->controlport = KopInteger(ob1); ob1 = getoa(ob,5); cp->dstate = KopInteger(ob1); ob1 = getoa(ob,6); cp->cstate = KopInteger(ob1); ob1 = getoa(ob,7); cp->humanio = KopInteger(ob1); ob1 = getoa(ob,8); cp->id = KopInteger(ob1); ob1 = getoa(ob,9); cp->type = KopInteger(ob1); ob1 = getoa(ob,10); if (ob1.tag == Snull) { cp->mathcapObjp = NULL; }else{ obp = (struct object *) sGC_malloc(sizeof(struct object)); *obp = ob1; cp->mathcapObjp = (void *)obp; } ob1 = getoa(ob,11); cp->engineByteOrder = KopInteger(ob1); ob1 = getoa(ob,12); cp->controlByteOrder = KopInteger(ob1); ob1 = getoa(ob,13); cp->engineID = KopInteger(ob1); return(0); } struct object KoxReq(struct object client, struct object func, struct object ob1) { int ans; static oxclientp cc1 = NULL; struct object rob = OINIT; rob.tag = Snull; if (cc1 == NULL) { cc1 = (oxclientp) mymalloc(sizeof(oxclient)); if (cc1 == NULL) { errorOxmisc2("KoxReq(): no more memory."); return(rob); } oxInitClient(cc1); } if (oxObjectToClient(client,cc1) == -1) return(rob); if (cc1 == NULL) { errorOxmisc2("KoxReq(): the first argument must be a client object."); return(rob); } if (func.tag != Sinteger) { errorOxmisc2("KoxReq(): the second argument must be an integer."); return(rob); } ans = oxReq(cc1,KopInteger(func),ob1); /* synchronize cc1 and client. */ oxClientToObject(cc1,client); return(KpoInteger(ans)); } struct object KoxGet(struct object client) { int ans,k; static oxclientp cc1 = NULL; struct object rob = OINIT; rob.tag = Snull; if (cc1 == NULL) { cc1 = (oxclientp) mymalloc(sizeof(oxclient)); if (cc1 == NULL) { errorOxmisc2("KoxGet(): no more memory."); return(rob); } oxInitClient(cc1); } if (oxObjectToClient(client,cc1) == -1) return(rob); if (cc1 == NULL) { errorOxmisc2("KoxGet(): the first argument must be a client object."); return(rob); } ans = oxGet(cc1,&rob,&k); /* synchronize cc1 and client. */ oxClientToObject(cc1,client); if (k) return(rob); else { return(KpoInteger(ans)); } } struct object KoxGetFromControl(struct object client) { int ans; static oxclientp cc1 = NULL; struct object rob = OINIT; rob.tag = Snull; if (cc1 == NULL) { cc1 = (oxclientp) mymalloc(sizeof(oxclient)); if (cc1 == NULL) { errorOxmisc2("KoxGetFromControl(): no more memory."); return(rob); } oxInitClient(cc1); } if (oxObjectToClient(client,cc1) == -1) return(rob); if (cc1 == NULL) { errorOxmisc2("KoxGetFromControl(): the first argument must be a client object."); return(rob); } ans = oxGetFromControl(cc1); /* synchronize cc1 and client. */ oxClientToObject(cc1,client); return(KpoInteger(ans)); } struct object KoxMultiSelect(struct object oclients,struct object t) { static int first = 1; static int csize = 0; static oxclientp *clients = NULL; oxclientp cc1; struct object rob = OINIT; int i; int tt; struct object ob1 = OINIT; struct object ob2 = OINIT; struct object ob0 = OINIT; int size; int ans; int dataready[1024]; int controlready[1024]; rob.tag = Snull; if (oclients.tag != Sarray) { errorOxmisc2("KoxMultiSelect(): the first argument must be an array."); return(rob); } size = getoaSize(oclients); if (first) { first = 0; csize = size; clients = (oxclientp *)mymalloc(sizeof(oxclientp)*(size+1)); if (clients == NULL) { errorOxmisc2("KoxMultiSelect(): no more memory."); return(rob); } for (i=0; idatafp2,stdout); /* synchronize cc1 and client. */ oxClientToObject(cc1,client); return(KpoInteger(ans)); } struct object KoxLog(struct object client,struct object in,struct object out) { int ans,k; static oxclientp cc1 = NULL; struct object rob = OINIT; rob.tag = Snull; if (cc1 == NULL) { cc1 = (oxclientp) mymalloc(sizeof(oxclient)); if (cc1 == NULL) { errorOxmisc2("KoxLog(): no more memory."); return(rob); } oxInitClient(cc1); } if (oxObjectToClient(client,cc1) == -1) return(rob); if (cc1 == NULL) { errorOxmisc2("KoxLog(): the first argument must be a client object."); return(rob); } if (in.tag != Sfile) { errorOxmisc2("KoxLog(): the second argument is not a file object."); return rob; } if (out.tag != Sfile) { errorOxmisc2("KoxLog(): the third argument is not a file object."); return rob; } k = fp2log(cc1->datafp2,in.rc.file,out.rc.file); fputc(cc1->engineByteOrder,out.rc.file); /* Output engineByteOrder. */ /* synchronize cc1 and client. */ oxClientToObject(cc1,client); return(KpoInteger(ans)); } struct object KoxLogStop(struct object client) { static oxclientp cc1 = NULL; struct object rob = OINIT; rob.tag = Snull; if (cc1 == NULL) { cc1 = (oxclientp) mymalloc(sizeof(oxclient)); if (cc1 == NULL) { errorOxmisc2("KoxLog(): no more memory."); return(rob); } oxInitClient(cc1); } if (oxObjectToClient(client,cc1) == -1) return(rob); if (cc1 == NULL) { errorOxmisc2("KoxLog(): the first argument must be a client object."); return(rob); } return(KpoInteger(fp2stopLog(cc1->datafp2))); } struct object KoxCloseClient(struct object client) { oxclientp cc1 = NULL; oxclient cc; struct object rob = OINIT; rob.tag = Snull; cc1 = &cc; if (oxObjectToClient(client,cc1) == -1) return(rob); if (cc1 == NULL) { errorOxmisc2("KoxCloseClient(): the first argument must be a client object."); return(rob); } fp2fflush(cc1->datafp2); if (cc1->humanio) { /* Do not close the file. */ return(KpoInteger(0)); } switch (cc1->type) { case CLIENT_SOCKET: fp2fclose(cc1->datafp2); {int r; r=close(cc1->controlfd);} break; case CLIENT_FILE: fp2fclose(cc1->datafp2); {int r; r=close(cc1->controlfd);} break; default: errorOxmisc2("Unknown client->type\n"); break; } oxClientListRemove(client); return(KpoInteger(0)); } static int cmoCheck00(struct object obj,int cmo[], int n) { int i,j,m; int ttt; #define CHECK00_N 4098 /* look up stackm.h and kclass.h */ static int typeTrans[CHECK00_N]; static int init = 0; /* if n == 0, report the cmo tag of the object obj. If it cannot be translated to cmo, then return -1. */ if (!init) { for (i=0; i= 199907170) { typeTrans[SuniversalNumber] = CMO_ZZ; }else{ typeTrans[SuniversalNumber] = CMO_ZZ_OLD; } typeTrans[Sarray] = CMO_LIST; /* typeTrans[Spoly] = CMO_DMS; */ typeTrans[Spoly] = CMO_DISTRIBUTED_POLYNOMIAL; typeTrans[Sdouble] = CMO_64BIT_MACHINE_DOUBLE; typeTrans[SrationalFunction] = CMO_RATIONAL; typeTrans[CLASSNAME_ERROR_PACKET] = CMO_ERROR2; typeTrans[CLASSNAME_mathcap] = CMO_MATHCAP; typeTrans[CLASSNAME_indeterminate] = CMO_INDETERMINATE; typeTrans[CLASSNAME_tree] = CMO_TREE; typeTrans[CLASSNAME_recursivePolynomial] = CMO_RECURSIVE_POLYNOMIAL; typeTrans[CLASSNAME_polynomialInOneVariable] = CMO_POLYNOMIAL_IN_ONE_VARIABLE; init = 1; } ttt = typeTrans[obj.tag]; if (obj.tag == Sclass) { ttt = typeTrans[ectag(obj)]; } /* Only report the cmo tag. */ if (n == 0) { if (ttt == 0) return(-1); else return(ttt); } for (i=0; i CMO tag)\n"); for (i=0; i<20; i++) { printf("%d ", typeTrans[i]); } printf("\n"); } fprintf(stderr,"The type of the argument object in sm1 is %d.\n",obj.tag); fprintf(stderr,"The type of the argument object in CMO is %d.\n",ttt); fprintf(stderr,"Available CMO tags in mathcap= %d elements : [ ",n); for (i=0; itag != Sarray) { fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n"); printObject(*obp,0,stderr); fprintf(stderr,"\n"); errorOxmisc2("cmoCheckMathCap: format error in the client->mathcapObjp field.\n"); } mathcap = *obp; /* Example of mathcap [ $mathcap-object$ , [ [ 199909080 , $Ox_system=ox_sm1.plain$ , $Version=2.991106$ , $HOSTTYPE=i386$ ] , [ 262 , 263 , 264 , 265 , 266 , 268 , 269 , 272 , 273 , 275 , 276 ] , [ [ 514 , [ 2130706434 , 1 , 2 , 4 , 5 , 17 , 19 , 20 , 22 , 23 , 24 , 25 , 26 , 30 , 31 , 60 , 61 , 27 , 33 , 40 , 16 , 34 ] ] ] ] ] */ n = getoaSize(mathcap); if (n < 2) { fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n"); printObject(*obp,0,stderr); fprintf(stderr,"\n"); errorOxmisc2("cmoCheckMathCap: length of mathcap is wrong in the client->mathcapObjp field.\n"); } ob0 = getoa(mathcap,0); if (ob0.tag != Sdollar) { fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n"); printObject(*obp,0,stderr); fprintf(stderr,"\n"); errorOxmisc2("cmoCheckMathCap: The first field must be the string mathcap-object.\n"); } if (strcmp(KopString(ob0),"mathcap-object") != 0) { fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n"); printObject(*obp,0,stderr); fprintf(stderr,"\n"); errorOxmisc2("cmoCheckMathCap: The mathcap must be of the form [(mathcap-object) [...]]\n"); } /* I should check getoa(getoa(mathcap,1),2) contains OX_DATA. It has not yet implemented. */ mathcapMain = getoa(mathcap,1); if (mathcapMain.tag != Sarray) { fprintf(stderr,"cmoCheckMathCap: mathcap[1] is \n"); printObject(mathcapMain,0,stderr); fprintf(stderr,"\n"); errorOxmisc2("cmoCheckMathCap: format error in the (client->mathcapObjp)[1] field. It should be an array.\n"); } if (getoaSize(mathcapMain) < 3) { fprintf(stderr,"cmoCheckMathCap: mathcap[1] is \n"); printObject(mathcapMain,0,stderr); fprintf(stderr,"\n"); errorOxmisc2("cmoCheckMathCap: format error in the (client->mathcapObjp)[1] field. It should be an array of which length is more than 2.\n"); } mathcapThird = getoa(mathcapMain,2); oxsize = getoaSize(mathcapThird); for (i=0; i 1) { cmolist = getoa(ox,1); if (cmolist.tag != Sarray) { fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n"); printObject(*obp,0,stderr); fprintf(stderr,"\n"); errorOxmisc2("cmoCheckMathCap: mathcap[1] must be an array of integers.\n"); } n = getoaSize(cmolist); if (n > CMO_CHECK_MATH_CAP_LIST_SIZE) { errorOxmisc2("cmoCheckMathCap: Too big cmo list.\n"); } for (i=0; idatafp2,OX_COMMAND,SerialOX++); oxSendInt32(cc1->datafp2,KopInteger(cmd)); /* synchronize cc1 and client. */ oxClientToObject(cc1,client); return(cmd); } struct object KoxPushCMO(struct object client,struct object ob) { int ans; static oxclientp cc1 = NULL; struct object rob = OINIT; rob.tag = Snull; if (cc1 == NULL) { cc1 = (oxclientp) mymalloc(sizeof(oxclient)); if (cc1 == NULL) { errorOxmisc2("KoxReq(): no more memory."); return(rob); } oxInitClient(cc1); /* BUG: is it fine? */ } if (oxObjectToClient(client,cc1) == -1) return(rob); if (cc1 == NULL) { errorOxmisc2("KoxReq(): the first argument must be a client object."); return(rob); } /* request to the data channel */ if (cc1->dstate != DSTATE_ANY) { errorOxmisc2("oxPushCMO: cc1->dstate != DSTATE_ANY, data channel is not ready to send data.\n"); return(rob); } if (!cmoCheckMathCap(ob,(struct object *)cc1->mathcapObjp)) { errorOxmisc2("oxPushCMO: your peer does not understand this cmo.\n"); return(rob); } oxSendOXheader(cc1->datafp2,OX_DATA,SerialOX++); cmoObjectToStream2(ob,cc1->datafp2); /* synchronize cc1 and client. */ oxClientToObject(cc1,client); return(ob); } oxclientp oxCreateControl_RFC_101(int fdstream,int portStream, int ipmask,char *pass); struct object KoxCreateControl_RFC_101(struct object peer,struct object ipmask,struct object pass) { struct object rob = OINIT; oxclientp client; int fdStream, portStream; int i; struct object ob1 = OINIT; rob.tag = Snull; if (peer.tag != Sarray) { errorOxmisc2("KoxCreateControl_RFC_101(): The first argument must be an array [fdStream, portStream]"); return(rob); } if (getoaSize(peer) != 2 ) { errorOxmisc2("KoxCreateControl_RFC_101(): The first argument must be an array [fdStream, portStream] of size 2."); return(rob); } for (i=0; idatafp2 = fp2open(fdStream); if (client->datafp2 == NULL) { fprintf(stderr,"oxCreateControl_RFC_101(): fp2open(fd) failed.\n"); return(NULL); } client->dataport = portStream; client->controlport = -1; client->controlfd = -1; client->id = oxGetClientID(); client->type = CLIENT_SOCKET; /* socket */ client->engineByteOrder = engineByteOrder; client->controlByteOrder = -1; return(client); } oxclientp oxCreateEngine_RFC_101(int fdstream,int portStream, int ipmask,char *pass, int engineID); struct object KoxCreateEngine_RFC_101(struct object peer,struct object ipmask,struct object pass, struct object engineID) { struct object rob = OINIT; oxclientp client; int fdStream, portStream; int i; struct object ob1 = OINIT; rob.tag = Snull; if (peer.tag != Sarray) { errorOxmisc2("KoxCreateEngine_RFC_101(): The first argument must be an array [fdStream, portStream]"); return(rob); } if (getoaSize(peer) != 2 ) { errorOxmisc2("KoxCreateEngine_RFC_101(): The first argument must be an array [fdStream, portStream] of size 2."); return(rob); } for (i=0; idatafp2 = fp2open(fdStream); if (client->datafp2 == NULL) { fprintf(stderr,"oxCreateEngine_RFC_101(): fp2open(fd) failed.\n"); return(NULL); } client->dataport = portStream; client->controlport = -1; client->controlfd = -1; client->id = oxGetClientID(); client->engineID = engineID; client->type = CLIENT_SOCKET; /* socket */ client->engineByteOrder = engineByteOrder; client->controlByteOrder = -1; return(client); } void oxClientListUpdate(struct object ob) { int id; extern struct object OxClientList[]; id = KopInteger(getoa(ob,8)); /* printf("id=%d\n",id); */ if ((id = 0)) { OxClientList[id] = ob; }else{ errorOxmisc2("oxClientListUpdate(): the client table is full.\n"); } } void oxClientListRemove(struct object ob) { int id; extern struct object OxClientList[]; id = KopInteger(getoa(ob,8)); if ((id = 0)) { (OxClientList[id]).tag = Snull; }else{ /* errorOxmisc2("oxClientListRemove(): the client table is full.\n");*/ } } static void KoxCleanClientList() { extern int OxClientListn; extern struct object OxClientList[]; int i,j,n; struct object ob = OINIT; n = 0; for (i=0; i= n) { j=0; errorOxmisc2("oxGetClientList(): the client table is broken.\n"); } putoa(rob,j,OxClientList[i]); j++; } } return rob; }