static void LoadModules()

in src/platform/ModulesManager.c [50:226]


static void LoadModules(const char* directory, const char* configJson)
{
    MODULE* module = NULL;
    DIR* dir = NULL;
    struct dirent* entry = NULL;
    char* path = NULL;
    char* clientName = NULL;
    int version = 0;
    JSON_Value* config = NULL;
    JSON_Object* configObject = NULL;
    JSON_Array* reportedArray = NULL;
    JSON_Object* reportedObject = NULL;
    REPORTED_OBJECT* reported = NULL;
    int reportedCount = 0;
    int reportedTotal = 0;
    int i = 0;
    int loaded = 0;
    ssize_t clientNameSize = 0;
    ssize_t reportedSize = 0;
    ssize_t pathSize = 0;

    if ((NULL == directory) || (NULL == configJson))
    {
        OsConfigLogError(GetPlatformLog(), "LoadModules(%p, %p) called with invalid arguments", directory, configJson);
    }
    else if (NULL == (config = json_parse_file(configJson)))
    {
        OsConfigLogError(GetPlatformLog(), "LoadModules: failed to parse configuration JSON '%s'", configJson);
    }
    else if (NULL == (configObject = json_value_get_object(config)))
    {
        OsConfigLogError(GetPlatformLog(), "LoadModules: failed to get config object");
    }
    else if (0 == (version = json_object_get_number(configObject, g_modelVersion)))
    {
        OsConfigLogError(GetPlatformLog(), "LoadModules: failed to get model version from configuration JSON '%s'", configJson);
    }
    else
    {
        OsConfigLogInfo(GetPlatformLog(), "LoadModules: loading modules from '%s'", directory);

        // "Azure OSConfig <version>;<osconfig version>" + null-terminator
        clientNameSize = strlen(AZURE_OSCONFIG) + strlen(OSCONFIG_VERSION) + 5;

        if (NULL == (clientName = (char*)malloc(clientNameSize)))
        {
            OsConfigLogError(GetPlatformLog(), "LoadModules: failed to allocate memory for client name");
        }
        else
        {
            memset(clientName, 0, clientNameSize);
            snprintf(clientName, clientNameSize, "%s %d;%s", AZURE_OSCONFIG, version, OSCONFIG_VERSION);
        }

        OsConfigLogInfo(GetPlatformLog(), "LoadModules: client name '%s'", clientName);
        errno = 0;

        if (NULL != (dir = opendir(directory)))
        {
            while (NULL != (entry = readdir(dir)))
            {
                if ((DT_REG != entry->d_type) ||
                    ((strcmp(entry->d_name, "") == 0) || (strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) ||
                    (NULL == strstr(entry->d_name, MODULE_EXT)))
                {
                    continue;
                }

                // <directory>/<module .so> + null-terminator
                pathSize = strlen(directory) + strlen(entry->d_name) + 2;

                if (NULL == (path = malloc(pathSize)))
                {
                    OsConfigLogError(GetPlatformLog(), "LoadModules: failed to allocate memory for path");
                    continue;
                }

                memset(path, 0, pathSize);
                snprintf(path, pathSize, "%s/%s", directory, entry->d_name);

                if (NULL != (module = LoadModule(clientName, path)))
                {
                    module->next = g_modules;
                    g_modules = module;
                    loaded++;
                }
                else
                {
                    OsConfigLogError(GetPlatformLog(), "LoadModules: failed to load module '%s'", entry->d_name);
                }

                FREE_MEMORY(path);
            }
            closedir(dir);
        }
        else
        {
            OsConfigLogError(GetPlatformLog(), "LoadModules: failed to open module directory '%s'", directory);
        }

        if (0 != errno)
        {
            OsConfigLogError(GetPlatformLog(), "LoadModules: failed during readdir() (%d)", errno);
        }

        if (loaded > 0)
        {
            OsConfigLogInfo(GetPlatformLog(), "Loaded %d modules from '%s'", loaded, directory);
        }
        else
        {
            OsConfigLogError(GetPlatformLog(), "No modules found in '%s'", directory);
        }
    }

    if (config && configObject)
    {
        if (NULL != (reportedArray = json_object_get_array(configObject, g_reportedObjectType)))
        {
            reportedCount = (int)json_array_get_count(reportedArray);

            if (0 < reportedCount)
            {
                reportedSize = sizeof(REPORTED_OBJECT) * reportedCount;

                if (NULL != (reported = (REPORTED_OBJECT*)malloc(reportedSize)))
                {
                    memset(reported, 0, reportedSize);

                    for (i = 0; i < reportedCount; i++)
                    {
                        if (NULL == (reportedObject = json_array_get_object(reportedArray, i)))
                        {
                            OsConfigLogError(GetPlatformLog(), "LoadModules: array element at index %d is not an object", i);
                        }
                        else if (NULL == (reported[i].component = (char*)json_object_get_string(reportedObject, g_componentName)))
                        {
                            OsConfigLogError(GetPlatformLog(), "LoadModules: object at index %d is missing '%s'", i, g_componentName);
                        }
                        else if (NULL == (reported[i].component = strdup(reported[i].component)))
                        {
                            OsConfigLogError(GetPlatformLog(), "LoadModules: failed to allocate memory for component name");
                        }
                        else if (NULL == (reported[i].object = (char*)json_object_get_string(reportedObject, g_objectName)))
                        {
                            OsConfigLogError(GetPlatformLog(), "LoadModules: object at index %d is missing '%s'", i, g_objectName);
                        }
                        else if (NULL == (reported[i].object = strdup(reported[i].object)))
                        {
                            OsConfigLogError(GetPlatformLog(), "LoadModules: failed to allocate memory for object name");
                        }
                        else
                        {
                            OsConfigLogDebug(GetPlatformLog(), "LoadModules: found reported property (%s.%s)", reported[i].component, reported[i].object);
                            reportedTotal++;
                        }
                    }

                    OsConfigLogInfo(GetPlatformLog(), "LoadModules: found %d reported objects in '%s'", reportedTotal, configJson);

                    g_reported = reported;
                    g_reportedTotal = reportedTotal;
                }
                else
                {
                    OsConfigLogError(GetPlatformLog(), "LoadModules: failed to allocate memory for reported objects");
                }
            }
        }
    }

    if (config)
    {
        json_value_free(config);
    }
    FREE_MEMORY(clientName);
}