int main()

in src/adapters/pnp/PnpAgent.c [486:746]


int main(int argc, char *argv[])
{
    char* connectionString = NULL;
    char* jsonConfiguration = NULL;
    char* proxyData = NULL;
    char* proxyHostAddress = NULL;
    int proxyPort = 0;
    char* proxyUsername = NULL;
    char* proxyPassword = NULL;
    int stopSignalsCount = ARRAY_SIZE(g_stopSignals);
    bool forkDaemon = false;
    pid_t pid = 0;
    char* osName = NULL;
    char* osVersion = NULL;
    char* cpuType = NULL;
    char* cpuVendor = NULL;
    char* cpuModel = NULL;
    long totalMemory = 0;
    long freeMemory = 0;
    char* kernelName = NULL;
    char* kernelRelease = NULL;
    char* kernelVersion = NULL;
    char* productName = NULL;
    char* productVendor = NULL;
    char* encodedProductInfo = NULL;

    forkDaemon = (bool)(((3 == argc) && (NULL != argv[2]) && (0 == strcmp(argv[2], FORK_ARG))) ||
        ((2 == argc) && (NULL != argv[1]) && (0 == strcmp(argv[1], FORK_ARG))));

    jsonConfiguration = LoadStringFromFile(CONFIG_FILE, false, GetLog());
    if (NULL != jsonConfiguration)
    {
        SetLoggingLevel(GetLoggingLevelFromJsonConfig(jsonConfiguration, GetLog()));
        SetMaxLogSize(GetMaxLogSizeFromJsonConfig(jsonConfiguration, GetLog()));
        SetMaxLogSizeDebugMultiplier(GetMaxLogSizeDebugMultiplierFromJsonConfig(jsonConfiguration, GetLog()));
        FREE_MEMORY(jsonConfiguration);
    }

    g_agentLog = OpenLog(LOG_FILE, ROLLED_LOG_FILE);

    if (forkDaemon)
    {
        ForkDaemon();
    }

    g_connectionStringSource = FromAis;

    // Re-open the log
    CloseLog(&g_agentLog);
    g_agentLog = OpenLog(LOG_FILE, ROLLED_LOG_FILE);

    OsConfigLogInfo(GetLog(), "OSConfig Agent starting (PID: %d, PPID: %d)", pid = getpid(), getppid());
    OsConfigLogInfo(GetLog(), "OSConfig version: %s", OSCONFIG_VERSION);

    if (IsDebugLoggingEnabled())
    {
        OsConfigLogWarning(GetLog(), "Debug logging is enabled. To disable debug logging, set 'LoggingLevel' to 6 in '%s' and restart OSConfig", CONFIG_FILE);
    }

    // Load remaining configuration
    jsonConfiguration = LoadStringFromFile(CONFIG_FILE, false, GetLog());
    if (NULL != jsonConfiguration)
    {
        g_modelVersion = GetModelVersionFromJsonConfig(jsonConfiguration, GetLog());
        g_numReportedProperties = LoadReportedFromJsonConfig(jsonConfiguration, &g_reportedProperties, GetLog());
        g_reportingInterval = GetReportingIntervalFromJsonConfig(jsonConfiguration, GetLog());
        g_isIotHubEnabled = IsIotHubManagementEnabledInJsonConfig(jsonConfiguration);
        g_iotHubProtocol = GetIotHubProtocolFromJsonConfig(jsonConfiguration, GetLog());
    }

    RestrictFileAccessToCurrentAccountOnly(CONFIG_FILE);

    snprintf(g_productName, sizeof(g_productName), g_productNameTemplate, g_modelVersion, OSCONFIG_VERSION);
    OsConfigLogInfo(GetLog(), "Product name: %s", g_productName);

    snprintf(g_modelId, sizeof(g_modelId), g_modelIdTemplate, g_modelVersion);
    OsConfigLogInfo(GetLog(), "Model id: %s", g_modelId);

    osName = GetOsName(GetLog());
    osVersion = GetOsVersion(GetLog());
    cpuType = GetCpuType(GetLog());
    cpuVendor = GetCpuVendor(GetLog());
    cpuModel = GetCpuModel(GetLog());
    totalMemory = GetTotalMemory(GetLog());
    freeMemory = GetFreeMemory(GetLog());
    kernelName = GetOsKernelName(GetLog());
    kernelRelease = GetOsKernelRelease(GetLog());
    kernelVersion = GetOsKernelVersion(GetLog());
    productVendor = GetProductVendor(GetLog());
    productName = GetProductName(GetLog());

    snprintf(g_productInfo, sizeof(g_productInfo), g_productInfoTemplate, g_modelVersion, OSCONFIG_VERSION, osName, osVersion,
        cpuType, cpuVendor, cpuModel, totalMemory, freeMemory, kernelName, kernelRelease, kernelVersion, productVendor, productName);

    if (NULL != (encodedProductInfo = UrlEncode(g_productInfo)))
    {
        if (strlen(encodedProductInfo) >= sizeof(g_productInfo))
        {
            OsConfigLogError(GetLog(), "Encoded product info string is too long (%d bytes, over maximum of %d bytes) and will be truncated",
                (int)strlen(encodedProductInfo), (int)sizeof(g_productInfo));
        }

        memset(g_productInfo, 0, sizeof(g_productInfo));
        memcpy(g_productInfo, encodedProductInfo, sizeof(g_productInfo) - 1);
    }

    OsConfigLogDebug(GetLog(), "Product info: '%s' (%d bytes)", g_productInfo, (int)strlen(g_productInfo));

    FREE_MEMORY(osName);
    FREE_MEMORY(osVersion);
    FREE_MEMORY(cpuType);
    FREE_MEMORY(cpuVendor);
    FREE_MEMORY(cpuModel);
    FREE_MEMORY(kernelName);
    FREE_MEMORY(kernelRelease);
    FREE_MEMORY(kernelVersion);
    FREE_MEMORY(productName);
    FREE_MEMORY(productVendor);
    FREE_MEMORY(encodedProductInfo);

    if (g_isIotHubEnabled)
    {
        OsConfigLogInfo(GetLog(), "Protocol: %s", (PROTOCOL_MQTT_WS == g_iotHubProtocol) ? "MQTT over Web Socket" : "MQTT");

        if (PROTOCOL_MQTT_WS == g_iotHubProtocol)
        {
            // Read the proxy options from environment variables, parse and fill the HTTP_PROXY_OPTIONS structure to pass to the SDK:
            if (NULL != (proxyData = GetHttpProxyData(GetLog())))
            {
                if (ParseHttpProxyData((const char*)proxyData, &proxyHostAddress, &proxyPort, &proxyUsername, &proxyPassword, GetLog()))
                {
                    // Assign the string pointers and trasfer ownership to the SDK
                    g_proxyOptions.host_address = proxyHostAddress;
                    g_proxyOptions.port = proxyPort;
                    g_proxyOptions.username = proxyUsername;
                    g_proxyOptions.password = proxyPassword;

                    FREE_MEMORY(proxyData);
                }
            }
        }

        if ((argc < 2) || ((2 == argc) && forkDaemon))
        {
            g_connectionStringSource = FromAis;
            if (NULL != (connectionString = RequestConnectionStringFromAis(&g_x509Certificate, &g_x509PrivateKeyHandle)))
            {
                if (0 != mallocAndStrcpy_s(&g_iotHubConnectionString, connectionString))
                {
                    OsConfigLogError(GetLog(), "Out of memory making copy of the connection string from AIS");
                    g_exitState = NoConnectionString;
                    goto done;
                }
            }
            else
            {
                OsConfigLogError(GetLog(), "Failed to obtain a connection string from AIS, to retry");
            }
        }
        else
        {
            if (0 == strncmp(argv[1], g_iotHubConnectionStringPrefix, strlen(g_iotHubConnectionStringPrefix)))
            {
                g_connectionStringSource = FromCommandline;
                if (0 != mallocAndStrcpy_s(&connectionString, argv[1]))
                {
                    OsConfigLogError(GetLog(), "Out of memory making copy of the connection string from the command line");
                    g_exitState = NoConnectionString;
                    goto done;
                }
            }
            else
            {
                g_connectionStringSource = FromFile;
                connectionString = LoadStringFromFile(argv[1], true, GetLog());
                if (NULL == connectionString)
                {
                    OsConfigLogError(GetLog(), "Failed to load a connection string from %s", argv[1]);

                    if (!IsWatcherActive())
                    {
                        g_exitState = NoConnectionString;
                        goto done;
                    }
                }
            }
        }

        if (connectionString && (0 != mallocAndStrcpy_s(&g_iotHubConnectionString, connectionString)))
        {
            OsConfigLogError(GetLog(), "Out of memory making copy of the connection string");
            goto done;
        }
    }

    for (int i = 0; i < stopSignalsCount; i++)
    {
        signal(g_stopSignals[i], SignalInterrupt);
    }
    signal(SIGHUP, SignalReloadConfiguration);
    signal(SIGUSR1, SignalProcessDesired);

    if (false == InitializeAgent())
    {
        OsConfigLogError(GetLog(), "Failed to initialize the OSConfig Agent");
        goto done;
    }

    // Call the Watcher to initialize itself
    InitializeWatcher(jsonConfiguration, GetLog());
    FREE_MEMORY(jsonConfiguration);

    while (0 == g_stopSignal)
    {
        AgentDoWork();

        SleepMilliseconds(DOWORK_SLEEP);

        if (0 != g_refreshSignal)
        {
            RefreshConnection();
            g_refreshSignal = 0;
        }
    }

done:
    OsConfigLogInfo(GetLog(), "OSConfig Agent (PID: %d) exiting with %d", pid, g_stopSignal);

    FREE_MEMORY(jsonConfiguration);
    FREE_MEMORY(g_x509Certificate);
    FREE_MEMORY(g_x509PrivateKeyHandle);
    FREE_MEMORY(connectionString);
    FREE_MEMORY(g_iotHubConnectionString);

    WatcherCleanup(GetLog());

    CloseAgent();

    StopAndDisableDaemon(OSCONFIG_PLATFORM, GetLog());

    CloseLog(&g_agentLog);

    // Once the SDK is done, we can free these

    if (g_proxyOptions.host_address)
    {
        free((void *)g_proxyOptions.host_address);
    }

    if (g_proxyOptions.username)
    {
        free((void *)g_proxyOptions.username);
    }

    if (g_proxyOptions.password)
    {
        free((void *)g_proxyOptions.password);
    }

    return 0;
}