*/
/********************************************************/
/* */
+/* Procedure to get the handle related to a remote */
+/* contact. */
+/* */
+/********************************************************/
+static int getcontact(SOCTYP *binding)
+
+{
+#define OPEP "unisoc.c:getcontac"
+int contact;
+socklen_t taille;
+struct sockaddr addr;
+
+contact=-1;
+taille=sizeof(addr);
+if ((contact=accept(binding->handle,&addr,&taille))<0) {
+ switch (errno) {
+ case EAGAIN :
+ /*well process not quick enough the handle was already */
+ /*accepted by another clement???. */
+ break;
+ case EINVAL : /*no socket avail anymore */
+ break;
+ default :
+ (void) rou_alert(0,"%s Unexpected error on IP/PORT <%s/%s> errno=<%s>",
+ OPEP,binding->ip,binding->port,strerror(errno));
+ break;
+ }
+ }
+else {
+ int flags;
+
+ if ((flags=fcntl(contact,F_GETFL,0))<0)
+ (void) rou_core_dump("%s Unable to get socket descripteur (error='%s')",
+ OPEP,strerror(errno));
+ if ((flags=fcntl(contact,F_SETFL,flags|O_NONBLOCK|O_ASYNC))<0)
+ (void) rou_core_dump("%s Unable to set socket descripteur (error='%s')",
+ OPEP,strerror(errno));
+ }
+return contact;
+#undef OPEP
+}
+/*
+\f
+*/
+/********************************************************/
+/* */
/* Procedure to free memory used by a */
/* binding info. */
/* */
^L
*/
/********************************************************/
+/* */
+/* Procedure to wait for an incoming connecion */
+/* from a remote client. */
+/* return a socket handle or -1 if trouble. */
+/* */
+/********************************************************/
+PUBLIC int soc_listen(SOCTYP *binding)
+
+{
+#define OPEP "unisoc.c:soc_listen"
+
+int contact;
+int phase;
+_Bool proceed;
+
+contact=-2;
+phase=0;
+proceed=true;
+while (proceed==true) {
+ switch (phase) {
+ case 0 : //checking if the point is ready;
+ if (binding==(SOCTYP *)0) {
+ (void) rou_alert(0,"%s binding pointer is NULL (Bug!?)",OPEP);
+ phase=999; //not going further
+ }
+ break;
+ case 1 : //checking if the handle is properly set
+ if (binding->handle<0) {
+ (void) rou_alert(0,"%s trouble with handle (handle value ='%d', Bug!?)",
+ OPEP,binding->handle);
+ phase=999; //not going further
+ }
+ break;
+ case 2 : //listening on the handle
+ fd_set reading;
+ struct timeval relax;
+ FD_ZERO(&reading);
+ FD_SET(binding->handle,&reading);
+ relax.tv_sec=1; //1 sec relax time
+ relax.tv_usec=0;
+ switch (select(binding->handle+1,&reading,(fd_set *)0,(fd_set *)0,&relax)) {
+ case -1 : //got a wrong return
+ switch (errno) {
+ case EINTR : //Received a signal, get out! fast!
+ phase=999;
+ break;
+ default : //Unexpected error?
+ (void) rou_core_dump("%, Unexpected select status (error=<%s>)",
+ OPEP,strerror(errno));
+ break; //never reached
+ }
+ break;
+ case 0 : //normal time out.
+ phase--; //lets continue to wait for incoming
+ break;
+ default : //we got a contact
+ if ((contact=getcontact(binding))<0)
+ phase--; //not quick enough, lets continue to wait
+ break;
+ }
+ break;
+ default : //SAFE Guard
+ proceed=false;
+ break;
+ }
+ phase++;
+ }
+return contact;
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
/* */
/* Procedure to "open/close" module and do */
/* homework purpose */