Ejemplo n.º 1
0
int
main(int argc, char *argv[])
{
    LSError lserror;
    LSErrorInit(&lserror);

    int public = HUB_TYPE_PUBLIC;
    int private = HUB_TYPE_PRIVATE;
    
    if (LSIsRunning(PID_DIR, MONITOR_PID_NAME))
    {
        g_critical("An instance of the monitor is already running");
        exit(EXIT_FAILURE);
    }
    
    mainloop = g_main_loop_new(NULL, FALSE);

    /* send message to hub to let clients know that they should start
     * sending us their messages */
    LSTransportHandlers handler_priv =
    {
        .msg_handler = _LSMonitorMessageHandlerPrivate,
        .msg_context = &private,
        .disconnect_handler = NULL,
        .disconnect_context = NULL,
        .message_failure_handler = NULL,
        .message_failure_context = NULL
    };
    
    LSTransportHandlers handler_pub =
    {
        .msg_handler = _LSMonitorMessageHandlerPublic,
        .msg_context = &public,
        .disconnect_handler = NULL,
        .disconnect_context = NULL,
        .message_failure_handler = NULL,
        .message_failure_context = NULL
    };

    _LSTransportSetupSignalHandler(SIGTERM, _HandleShutdown);
    _LSTransportSetupSignalHandler(SIGINT, _HandleShutdown);

    _HandleCommandline(argc, argv);

    if (list_clients || list_subscriptions || list_malloc)
    {
        handler_priv.msg_handler = _LSMonitorListMessageHandler;
        handler_pub.msg_handler = _LSMonitorListMessageHandler;
    }

    if (!_LSTransportInit(&transport_priv, MONITOR_NAME, &handler_priv, &lserror))
    {
        goto error;
    }
    
    if (!_LSTransportInit(&transport_pub, MONITOR_NAME, &handler_pub, &lserror))
    {
        goto error;
    }
   
    /* connect for "private" messages */ 
    if (!_LSTransportConnect(transport_priv, true, false, &lserror))
    {
        goto error;
    }

    /* connect for "public" messages */
    if (!_LSTransportConnect(transport_pub, true, true, &lserror))
    {
        goto error;
    }
   
    _LSTransportGmainAttach(transport_priv, g_main_loop_get_context(mainloop)); 
    _LSTransportGmainAttach(transport_pub, g_main_loop_get_context(mainloop)); 

    if (_LSTransportGetTransportType(transport_priv) == _LSTransportTypeLocal)
    {
        transport_priv_local = true;

        /* message printing callback */
        //g_idle_add(_LSMonitorIdleHandlerPrivate, NULL);
        private_queue = _LSMonitorQueueNew(false);
        g_timeout_add(500, _LSMonitorIdleHandlerPrivate, private_queue);
    }

    if (_LSTransportGetTransportType(transport_pub) == _LSTransportTypeLocal)
    {
        transport_pub_local = true;
        
        //g_idle_add(_LSMonitorIdleHandlerPublic, NULL);
        public_queue = _LSMonitorQueueNew(true);
        g_timeout_add(500, _LSMonitorIdleHandlerPublic, public_queue);
    }

    if (list_clients || list_subscriptions || list_malloc)
    {
        if (!_LSTransportSendMessageListClients(transport_priv, &lserror))
        {
            goto error;
        }

        if (!_LSTransportSendMessageListClients(transport_pub, &lserror))
        {
            goto error;
        }
    } 
    else
    {
        /* send the message to the hub to tell clients to connect to us */
        if (!LSTransportSendMessageMonitorRequest(transport_priv, &lserror))
        {
            goto error;
        }
        
        if (!LSTransportSendMessageMonitorRequest(transport_pub, &lserror))
        {
            goto error;
        }

        if (debug_output)
        {
            fprintf(stdout, "Debug\tTime\t\tProt\tType\tSerial\t\tSender\t\tDestination\t\tMethod                            \tPayload\n");
        }
        else
        {
            fprintf(stdout, "Time\t\tProt\tType\tSerial\t\tSender\t\tDestination\t\tMethod                            \tPayload\n");
        }
    }

    dup_hash_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
    LS_ASSERT(dup_hash_table);

    g_main_loop_run(mainloop);
    g_main_loop_unref(mainloop);

    _DisconnectCustomTransport();

    g_hash_table_destroy(dup_hash_table);

    exit(EXIT_SUCCESS);

error:
    LSErrorPrint(&lserror, stderr);
    LSErrorFree(&lserror);
    exit(EXIT_FAILURE);
}
/** 
 *******************************************************************************
 * @brief Allocate a new client.
 * 
 * @param  transport        IN  transport 
 * @param  fd               IN  fd 
 * @param  service_name     IN  client service name 
 * @param  unique_name      IN  client unique name 
 * @param  outgoing         IN  outgoing queue (NULL means allocate) 
 * @param  initiator        IN  true if this is the end of the connection that initiated the connection
 * 
 * @retval client on success
 * @retval NULL on failure
 *******************************************************************************
 */
_LSTransportClient*
_LSTransportClientNew(_LSTransport* transport, int fd, const char *service_name, const char *unique_name, _LSTransportOutgoing *outgoing, bool initiator)
{
    _LSTransportClient *new_client = g_slice_new0(_LSTransportClient);

    if (!new_client)
    {
        g_debug("OOM when attempting to add new incoming connection");
        return NULL;
    }

    //new_client->sh = sh;
    new_client->service_name = g_strdup(service_name);
    new_client->unique_name = g_strdup(unique_name);
    new_client->transport = transport;
    new_client->state = _LSTransportClientStateInvalid;
    new_client->is_sysmgr_app_proxy = false;
    new_client->is_dynamic = false;
    new_client->initiator = initiator;

    _LSTransportChannelInit(transport, &new_client->channel, fd, transport->source_priority);

    new_client->cred = _LSTransportCredNew();
    if (!new_client->cred)
    {
        goto error;
    }

    /* Get pid, gid, and uid of client if we're local. It won't work for obvious
     * reasons if it's a TCP/IP connection */
    if (_LSTransportGetTransportType(transport) == _LSTransportTypeLocal)
    {
        LSError lserror;
        LSErrorInit(&lserror);

        if (!_LSTransportGetCredentials(fd, new_client->cred, &lserror))
        {
            LSErrorPrint(&lserror, stderr);
            LSErrorFree(&lserror);
        }
    }

    if (outgoing)
    {
        new_client->outgoing = outgoing;
    }
    else
    {
        new_client->outgoing = _LSTransportOutgoingNew();
        if (!new_client->outgoing)
        {
            goto error;
        }
    }

    new_client->incoming = _LSTransportIncomingNew();
    if (!new_client->incoming)
    {
        goto error;
    }

    return new_client;

error:

    if (new_client->service_name) g_free(new_client->service_name);
    if (new_client->unique_name) g_free(new_client->unique_name);

    if (new_client->outgoing && !outgoing)
    {
        _LSTransportOutgoingFree(new_client->outgoing);
    }
    if (new_client->incoming)
    {
        _LSTransportIncomingFree(new_client->incoming);
    }
    if (new_client)
    {
        g_slice_free(_LSTransportClient, new_client);
    }

    return NULL;
}