// $Header: /usr/u/moudgill/project/Socket/RCS/server2.C,v 1.6 1992/10/02 18:34:02 moudgill Exp moudgill $
// 17th December, 1991. Mayan Moudgill.

static const char rcsid[] = "$Id: server2.C,v 1.6 1992/10/02 18:34:02 moudgill Exp moudgill $";

#include "sstream.h"
#ifdef __linux__
#include <stdlib.h>
#else
#include <osfcn.h>
#endif

void pipedef(sstream& s)
{
   cerr << "lost other end of " << s.sd() << "\n";
   exit(1);
}


const int maxsocks = 8;
int       num = 0;
int       n[maxsocks];
sstream   c[maxsocks];

int left()
{
   if( num > 0) {
      return 1;
   }
   for(int i =0 ; i < maxsocks; i++) {
      if( n[i] != 0)
	 return 1;
   }
   return 0;
}

int  getnum(sstream& s)
{
   for(int i = 0; s.sd() != c[i].sd(); i++) {
   }
   return i;
}

void getcount(sstream& s, int x)
{
   cerr << "going to process " << x << " numbers for " << s.sd() << "\n";
   n[getnum(s)] = x;
}

void  negnum(sstream &t, int)
{
int c;
int p;

   t >> c;
   if( !t ) {
      cerr << "couldn't recv\n" ;
      exit(2);
   }
   cerr << "read " << c << " from " << t.sd() << "\n";
   t << (-c) << "\n" ;
   if( !t ) {
      cerr << "couldn't send\n";
      exit(3);
   }
   p = getnum(t);
   n[p]--;
   if( n[p] <= 0 ) {
      t.close();
   }
} 

void getconnect(sstream& s, int)
{
   c[--num].accept(s);
   n[num] = -1;
   c[num].sstate(sstream::unitbufferbit);
   if( !c[num] ) {
      cerr << "could not accept connection #" << num << "\n";
      exit(6);
   }
   cerr << "connection #" << num << " " << c[num].sd() << " to "
	 << c[num].tohost() << " " << c[num].toport() << "\n";

   c[num].pipehandler(pipedef);
   c[num].urghandler(getcount);
   c[num].iohandler(negnum);
   if( num == 0) {
      cerr << "closing server port\n";
      s.close();
   }
}

void main(int argc, char * argv[])
{
sstream   s;

   if( argc < 3) {
      cerr << "error: usage : " << argv[0] << " <port> <# connect>\n";
      exit(4);
   }
   num = atoi(argv[2]);
   s.setbuf(0,0);
   s.open(atoi(argv[1]));
   s.iohandler(getconnect);

   if( !s  ) {
      cerr << "could not open\n";
      exit(5);
   }

   cerr << "server " << s.sd() << " bound to " << s.host() << " "
	 << s.port() << "\n";

   while( left()) {
     cerr << "pausing\n";
     pause();
   }
}
