/**
*
*  @File : exo_02s.cxx
*
*  @Authors : D. Mathieu
*             M. Laporte
*
*  @Date : 19/12/2000
*
*  @Version : V1.0
*
*  @Synopsis : Serveur acceptant une connexion soit Internet soit locale
*
**/
#include <iostream>
#include <string>
#include <exception>

#include <cctype>         // fd_set
#include <sys/select.h>   // FD_ISSET(), FD_ZERO(), FD_SET()
#include <netinet/in.h>   // htons()
#include <sys/socket.h>   // getsockname()

#include "CExc.h"
#include "nsSysteme.h"
#include "nsNet.h"

using namespace nsSysteme;
using namespace nsNet;

namespace
{
    int CharGen (int sdComm)
    {
        char LigneInet [] = "Domaine d'adressage Internet";
        LigneInet [sizeof (LigneInet) - 1] = '\n';
        char LigneLocal [] = "Domaine d'adressage local";
        LigneLocal [sizeof (LigneLocal) - 1] = '\n';
       
        struct sockaddr_bidon
        {
            unsigned short af_family;
            char           bidon [108];
        } addr;

        socklen_t len = sizeof (addr);

        ::getsockname (sdComm, (sockaddr * ) &addr, &len);

        for (int i = 10; --i; )
            if (AF_INET == addr.af_family)
                Write (sdComm, LigneInet,  sizeof (LigneInet));
            else
                Write (sdComm, LigneLocal, sizeof (LigneLocal));
       
        Close (sdComm);

        return 0;

    } // CharGen()

} // namespace anonyme

int std::ppal (int argc, char * argv []) throw (exception)
{
    if (1 != argc)
        throw nsBAO::CExc (string ("Usage : ") + argv [0]);

    char NomSock [] = "/tmp/chargen";
    unsigned short NumPort = ::htons (62001);

    const int sdTCP    = ServeurSockInStream (NumPort);
    const int sdLocale = ServeurSockUnStream (NomSock);

    fd_set MaskRead;
    FD_ZERO (&MaskRead);
    FD_SET  (sdTCP, &MaskRead);
    for (;;)
    {
        FD_SET  (sdTCP,    &MaskRead);
        FD_SET  (sdLocale, &MaskRead);
        Select (sdLocale + 1, &MaskRead);

        const int sdComm = ServeurAccept (FD_ISSET (sdLocale, &MaskRead)
                                                          ? sdLocale : sdTCP);
        if (! Fork ())
        {
            Close (sdLocale);
            Close (sdTCP);
            return CharGen (sdComm);
        }
        Close (sdComm);
    }
    Close (sdLocale);
    Close (sdTCP);

    return 0;

} // ppal()